openssl 암호화프로그래밍... EVP
글쓴이: dulra82 / 작성시간: 화, 2009/04/14 - 10:34오전
EVP를 사용하여 텍스트를 암호화하고 복호화하는 프로그래밍입니다.
------------------------test.c-------------------------------------------
#include stdio.h #include "cipher.h" int main(void) { unsigned char* cipherText = (unsigned char*)malloc(sizeof(unsigned char) * 1024); unsigned char* plainText = (unsigned char*)malloc(sizeof(unsigned char) * 1024); char* key = "ABCsdf2asdf"; int length = 0; strcpy((char*)plainText, "This is TestProgram...!"); printf("plainText = %s lengths = %d\n", plainText, strlen(plainText)); length = encrypt_block(cipherText, plainText, strlen((char*)plainText),(unsigned char*)key); printf("After Encrypt : %s\n", cipherText); printf("=======================================\n"); length = decrypt_block(plainText, cipherText, strlen((char*)cipherText), (unsigned char*)key); plainText[length] = '\0'; printf("After Decrypt : %s lengths = %d\n", plainText, strlen(plainText)); return 0; } ----------------------------------cipher.h---------------------------------- #include openssl/evp.h #include openssl/err.h #include openssl/ssl.h int encrypt_block(unsigned char* cipherText, unsigned char* plainText, unsigned int plainTextLen, unsigned char* key); int decrypt_block(unsigned char* plainText, unsigned char* cipherText, unsigned int cipherTextLen, unsigned char* key); /* AES Encrypt Process */ int encrypt_block(unsigned char* cipherText, unsigned char* plainText, unsigned int plainTextLen, unsigned char* key) { EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX)); int addLen = 0, orgLen = 0; unsigned long err = 0; ERR_load_crypto_strings(); EVP_CIPHER_CTX_init(ctx); if(EVP_EncryptInit(ctx, EVP_aes_128_cbc(), key, NULL) != 1) { err = ERR_get_error(); printf("ERR : EVP_Encrypt() - %s\n", ERR_error_string(err, NULL)); return -1; } if(EVP_EncryptUpdate(ctx, cipherText, &orgLen, plainText, plainTextLen) != 1) { err = ERR_get_error(); printf("ERR : EVP_EncryptUpdate() - %s\n", ERR_error_string(err, NULL)); return -1; } if (EVP_EncryptFinal(ctx, cipherText + orgLen, &addLen) != 1) { err = ERR_get_error(); printf("ERR: EVP_EncryptFinal() - %s\n", ERR_error_string (err, NULL)); return -1; } EVP_CIPHER_CTX_cleanup(ctx); ERR_free_strings(); return addLen + orgLen; } /* AES Decrypt Process */ int decrypt_block(unsigned char* plainText, unsigned char* cipherText, unsigned int cipherTextLen, unsigned char* key) { EVP_CIPHER_CTX *ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX)); unsigned long err = 0; int toLen = 0, outLen = 0; int ret = 0; ERR_load_crypto_strings(); EVP_CIPHER_CTX_init(ctx); if (EVP_DecryptInit(ctx, EVP_aes_128_cbc(), key, NULL) != 1) { err = ERR_get_error(); printf("ERR: EVP_DecryptInit() - %s\n", ERR_error_string (err, NULL)); return -1; } if (EVP_DecryptUpdate(ctx, plainText, &toLen, cipherText, cipherTextLen) != 1) { err = ERR_get_error(); printf("ERR: EVP_DecryptUpdate() - %s\n", ERR_error_string (err, NULL)); return -1; } if (EVP_DecryptFinal(ctx, &plainText[cipherTextLen], &outLen) != 1) { err = ERR_get_error(); printf("ERR: EVP_DecryptFinal() - %s\n", ERR_error_string (err, NULL)); return -1; } EVP_CIPHER_CTX_cleanup(ctx); ERR_free_strings(); ret = toLen + outLen; return ret; }
이것을 실행하면... 대부분은 잘 작동하는데... 복호화할때 가끔씩 문자가 깨질때가 있습니다.
plainText를 바꾸거나 key값을 바꾸거나 하면 복호화할 때 문제가 생기네요.
해결법을 도저히 몰라서 여기에 여쭙게되었습니다. 터미널에서 실행하면 문자가 완전히깨져서 터미널을 끄고 다시 켜야하는 상황이 나오네요ㅠ.
여담) #include 꺽쇠stdio.h꺽쇠 <-- 이렇게 올릴려고 하는데 안되서 꺽쇠를 빼버렸습니다. 그냥텍스트로 올리는데도 꺽쇠가 표시가 되질 않네요.,
Forums:
함수를 뒤져보세요.
글자가 깨지는 경우는 함수에서 마지막 비트에 문자의 끝을 나타내는 어떤 기호를 넣는 경우,
함수간 글자를 옮기는 과정에서 글자가 깨져 나올 수 있습니다.
글자 처리하는 함수를 뒤져서 문자를 몇 비트에 어떻게 넣고 문자의 끝을 어떻게 처리하는지
뒤져보면 문제가 해결될 것 같습니다.
------------------------------------------------------------
적당한 운동은 뱃살을.. 눈을 깜박이는 센스는 안구건조증을 예방합니다.
조금씩 마셔주는 물 한모금은 컴으로인한 피로를 조금은 줄여줍니다.
------------------------------------------------------------
적당한 운동은 뱃살을.. 눈을 깜박이는 센스는 안구건조증을 예방합니다.
조금씩 마셔주는 물 한모금은 컴으로인한 피로를 조금은 줄여줍니다.
encrypt_block함수에서
encrypt_block함수에서 반환할 때에는 리턴되는 length길이만큼 문자가 생성되고 마지막에 '\0'를 자동으로 삽입해줍니다.
반면에 decrypt_block함수에서는 리턴되는 length에서는 마지막에 '\0'를 삽입해주지 않아서 '\0'를 강제적으로 삽입하였습니다.
그리고 decrypt_block함수에서 3번째 인자를 length로 바꾸었습니다.(암호문에서 중간에 있을지 모르는 '\0'때문에 인자를 바꿈)
여기서 출력을 암호문과 복호화된 텍스트를 출력하면...(키를 계속 바꿔서 생성하였습니다.)
가끔씩 텍스트가 깨집니다.(터미널 상에 나오는 모든 텍스트가 다 깨져버립니다.)
그런데 출력을 복호화된 텍스트만 출력하면 아무런 이상이 없습니다.
무엇이 문제일까요? ㅠㅠ?
라이브러리 버전이 몇 인지는 모르겠지만..
라이브러리 버전이 몇 인지 모르겠지만 rpm이나 컴파일 된 것을 사용하지 않는다면
라이브러리 소스를 직접 컴파일해서 사용했을 텐데, 라이브러리 소스를 한 번 뒤저 보는 것도 괜찮을 듯 싶습니다.
-----------------------------------------------------------
적당한 운동은 뱃살을.. 눈을 깜박이는 센스는 안구건조증을 예방합니다.
조금씩 마셔주는 물 한모금은 컴으로인한 피로를 조금은 줄여줍니다.
------------------------------------------------------------
적당한 운동은 뱃살을.. 눈을 깜박이는 센스는 안구건조증을 예방합니다.
조금씩 마셔주는 물 한모금은 컴으로인한 피로를 조금은 줄여줍니다.
block cipher이기 때문에
block cipher이기 때문에 끝에 블럭 크기에 딱 안 맞는 부분은 padding이 들어가야 암호화가 됩니다. 마찬가지로 복호화할 때도 padding을 빼야 되고요. *Update() 함수는 블럭 경계를 넘어간 부분만 암호화/복호화하고 나머지는 버퍼에 남겨둡니다.
자동으로 padding을 넣고 빼는 방법이 있는데 생각이 안 나고, 일단 코드를 보면 EVP_DecryptFinal()에서 toLen이 들어가야 할 곳에 cipherTextLen을 쓰신 것 같네요.
자동으로 padding을
자동으로 padding을 넣고 빼는 것은 default로 되어 있는것 같네요.
고치는 것은 EVP_CIPHER_CTX_set_padding(); 이 함수로 하는것 같은데.. 넣었다 뺐다해도 별반 차이가 없네요.
EVP_DecryptFinal() 부분은 수정했습니다. 변수를 잘못넣었네요;;
그래도 여전히 가끔씩 텍스트가 깨지는 현상이 발생하네요 ㅠ
라이브러리소스는 ubuntu 까니까 미리 깔려있던걸로 사용하고 있습니다.
댓글 달기