일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- samp;e_frac()
- mutate()
- filter()
- summarize()
- distinct()
- groupe_by()
- dplyr
- sample_n()
- 대칭형 알고리즘
- arrange()
- select()
- proc contents
- AES
- Today
- Total
Gae Ko's Blog
[암호] aes_256_cbc 암호화 알고리즘 소스 코드 본문
다음은 openssl을 사용한 aes_256_cbc 암호화 알고리즘 소스 코드이다. 소스코드를 보고 분석하여 보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | #include <string.h> #include <stdio.h> #include <stdlib.h> #include <openssl/evp.h> #include <openssl/aes.h> #include <time.h> void aes_256_cbc(FILE *ifp, FILE *ofp, unsigned char *ckey, unsigned char *ivec) { const unsigned BUFSIZE = 4096; unsigned char *read_buf = malloc(BUFSIZE); // 암호화할 메세지를 읽어올 공간 unsigned char *cipher_buf; // 암호화한 결과 메세지를 저장할 공간 unsigned blocksize; int out_len; EVP_CIPHER_CTX *ctx; // 암호화 수행에 사용할 context // EVP 암호 초기화 ctx = EVP_CIPHER_CTX_new(); // EVP 암호화 초기 설정 // - context, 암호 ㄹ고리즘, 키 값, IV값 설정 EVP_CipherInit(ctx, EVP_aes_256_cbc(), ckey, ivec, 0); blocksize = EVP_CIPHER_CTX_block_size(ctx); cipher_buf = malloc(BUFSIZE + blocksize); // block size보다 추가적인 크기를 가짐 (padding 등의 이유) while(1) { // Read in data in blocks until EOF. Update the ciphering with each read. int numRead = fread(read_buf, sizeof(unsigned char), BUFSIZE, ifp); // 입력파일에서 BUFSIZE만큼 데이터를 read EVP_CipherUpdate(ctx, cipher_buf, &out_len, read_buf, numRead); // read된 데이토를 암호화 fwrite(cipher_buf, sizeof(unsigned char), out_len, ofp); // 출력 파일에 암호화된 데이터를 write if (numRead < BUFSIZE) { // EOF : 블록의 크기보다 작은 데이터부터 더이상 암호화가 진행되지 않는다. break; } } // Now cipher the final block and write it out. EVP_CipherFinal(ctx, cipher_buf, &out_len); // 블록사이즈가 맞지 않아 UPDATE()에서 처리가 안된 데이터를 처리. fwrite(cipher_buf, sizeof(unsigned char), out_len, ofp); // Free memory free(cipher_buf); free(read_buf); EVP_CIPHER_CTX_free(ctx); } int main(int argc, char *argv[]) { unsigned char ckey[] = "thiskeyisverybaddontusethisinput"; // key 값 unsigned char ivec[] = "dontusethisinputaatwosdfjjienone"; // IV 값 FILE *fIN, *fOUT; // 입출력 파일의 파일 포인터 float gap; time_t startTime = 0; time_t endTime = 0; // main함수의 매개변수인 inputFile과 outputFile를 쓰지 않는 경우 if(argc <= 2) { fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]); exit(EXIT_FAILURE); } //startTime 셋팅 startTime = clock(); //암호화 시작 fIN = fopen(argv[1], "rb"); //File to be encrypted; plain text 암호화할 파일 열기 fOUT = fopen(argv[2], "wb"); //File to be written; cipher text 암호화한 결과를 저장할 파일 열기 aes_256_cbc(fIN, fOUT, ckey, ivec); fclose(fIN); fclose(fOUT); //endTime 저장 endTime = clock(); //암호화하는 데에 걸린 시간 계산하고 출력하기 gap = (float)(endTime-startTime)/(CLOCKS_PER_SEC); printf("시간 : %f 초 \n", gap); } | cs |
1. EVP
- 수많은 Openssl의 암호 api를 하나의 인터페이스로 구성.
- The EVP interface, which can be accessed by including "openssl/evp.h"
2. CTX
- Context
- EVP로 Encryption, Decryption 등 각 수행에 필요하거나 변경되는 정보들을 유지하는 구조체.
- 암호화 알고리즘, 키(key)값, IV(initializarion vector)값, padding 설정 등등에 관한 정보
- 대칭키 암호에서는 EVP_CIPHER_CTX 구조체를 사용.
3. EVP Cipher API
- EVP 사용하여 암호 알고리즘이나 방식 등에 상관없이 여러 암호 알고리즘을 동일한 루틴으로 사용 가능.
- 암호/복호화의 동작 루틴은 동일하고 사용되는 함수명만 다름.
4. 암호 context의 정의와 초기화
- void EVP_CHPHER_CTX_new(EVP_CIPHER_CRT *ctx);
- cipher context를 초기화
- ctx : cipher context의 주소
5. EVP 암호/복호화 초기 설정
- int EVP_CipherInit(EVP_CIPHER_CRT *ctx, const EVP_CIPHER *type, unsigned char *key, unsigned char *iv, int enc);
- 암호/복호화 하기 위한 초기 설정
- 성공시 1, 실패시 0을 리턴
- ctx : 사용되는 cipher context
- type : 암호화 알고리즘. ex. EVP_des_ecd(), EVP_aes_256_cbc(), ... 등
- key : binary key 값. 암호 알고리즘에 따라 길이가 잘림.
- iv : binary iv 값. 암호 알고리즘에 따라 길이가 잘림. ECB mode에서는 NULL로 설정하는데 값이 있어도 사용되지 않음.
- enc : 암호/복호화 flag. 1이면 암호화, 0이면 복호화.
6. EVP 암호/복호화 수행
- int EVP_CipherUpdate(EVP_CIPHER_CRT *ctx, unsigned char *out, int *outl, unsigned char *in, int inl);
- 실질적으로 데이터를 암호/복호화 한다.
- 성공시 1, 실패시 0 리턴
- block size가 맞지 않으면, Final( )에서 처리. (ECB/CBC mode처럼 block cipher인 경우)
- ctx : 사용되는 cipher context
- out : 암호/복호화된 데이터가 저장될 버퍼
- outl : out의 길이가 저장될 변수로 암호/복호화된 데이터의 길이
- in : 입력 데이터 (=암호화시 평문=복호화시 암호문)
- inl : in의 길이
- EVP_CipherFinal(EVP_CIPHER_CRT *ctx, unsigned char *out, int *outl)
- 패딩 및 필요한 작업을 처리
- 성공시 1, 실패시 0 리턴
- block size가 맞지 않아 Update( )에서 처리가 안된 데이터를 처리. (ECB/CBC mode처럼 block cipher인 경우)
- ctx : 사용되는 cipher context
- out : 암호/복호화된 데이터가 저장될 버퍼
- outl : out의 길이가 저장될 변수
* 참고한 사이트
http://blog.naver.com/PostView.nhn?blogId=seongjeongki7&logNo=220886192615
'암호' 카테고리의 다른 글
[암호] 비트맵 파일 암호화하기 (0) | 2018.01.24 |
---|---|
[암호] 암호화 알고리즘에 따른 암호화 속도 비교하기 (1) | 2018.01.24 |
[암호] SEED (0) | 2018.01.16 |
[암호] AES (0) | 2018.01.15 |
[암호] 블록암호의 운용모드 (0) | 2018.01.15 |