openssl 암호화프로그래밍... EVP

dulra82의 이미지

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꺽쇠 <-- 이렇게 올릴려고 하는데 안되서 꺽쇠를 빼버렸습니다. 그냥텍스트로 올리는데도 꺽쇠가 표시가 되질 않네요.,

whitefly의 이미지


글자가 깨지는 경우는 함수에서 마지막 비트에 문자의 끝을 나타내는 어떤 기호를 넣는 경우,
함수간 글자를 옮기는 과정에서 글자가 깨져 나올 수 있습니다.
글자 처리하는 함수를 뒤져서 문자를 몇 비트에 어떻게 넣고 문자의 끝을 어떻게 처리하는지
뒤져보면 문제가 해결될 것 같습니다.
------------------------------------------------------------
적당한 운동은 뱃살을.. 눈을 깜박이는 센스는 안구건조증을 예방합니다.
조금씩 마셔주는 물 한모금은 컴으로인한 피로를 조금은 줄여줍니다.

------------------------------------------------------------
적당한 운동은 뱃살을.. 눈을 깜박이는 센스는 안구건조증을 예방합니다.
조금씩 마셔주는 물 한모금은 컴으로인한 피로를 조금은 줄여줍니다.

dulra82의 이미지

encrypt_block함수에서 반환할 때에는 리턴되는 length길이만큼 문자가 생성되고 마지막에 '\0'를 자동으로 삽입해줍니다.
반면에 decrypt_block함수에서는 리턴되는 length에서는 마지막에 '\0'를 삽입해주지 않아서 '\0'를 강제적으로 삽입하였습니다.
그리고 decrypt_block함수에서 3번째 인자를 length로 바꾸었습니다.(암호문에서 중간에 있을지 모르는 '\0'때문에 인자를 바꿈)

여기서 출력을 암호문과 복호화된 텍스트를 출력하면...(키를 계속 바꿔서 생성하였습니다.)
가끔씩 텍스트가 깨집니다.(터미널 상에 나오는 모든 텍스트가 다 깨져버립니다.)
그런데 출력을 복호화된 텍스트만 출력하면 아무런 이상이 없습니다.

무엇이 문제일까요? ㅠㅠ?

whitefly의 이미지

라이브러리 버전이 몇 인지 모르겠지만 rpm이나 컴파일 된 것을 사용하지 않는다면
라이브러리 소스를 직접 컴파일해서 사용했을 텐데, 라이브러리 소스를 한 번 뒤저 보는 것도 괜찮을 듯 싶습니다.
-----------------------------------------------------------
적당한 운동은 뱃살을.. 눈을 깜박이는 센스는 안구건조증을 예방합니다.
조금씩 마셔주는 물 한모금은 컴으로인한 피로를 조금은 줄여줍니다.

------------------------------------------------------------
적당한 운동은 뱃살을.. 눈을 깜박이는 센스는 안구건조증을 예방합니다.
조금씩 마셔주는 물 한모금은 컴으로인한 피로를 조금은 줄여줍니다.

cwryu의 이미지

block cipher이기 때문에 끝에 블럭 크기에 딱 안 맞는 부분은 padding이 들어가야 암호화가 됩니다. 마찬가지로 복호화할 때도 padding을 빼야 되고요. *Update() 함수는 블럭 경계를 넘어간 부분만 암호화/복호화하고 나머지는 버퍼에 남겨둡니다.

자동으로 padding을 넣고 빼는 방법이 있는데 생각이 안 나고, 일단 코드를 보면 EVP_DecryptFinal()에서 toLen이 들어가야 할 곳에 cipherTextLen을 쓰신 것 같네요.

dulra82의 이미지

자동으로 padding을 넣고 빼는 것은 default로 되어 있는것 같네요.
고치는 것은 EVP_CIPHER_CTX_set_padding(); 이 함수로 하는것 같은데.. 넣었다 뺐다해도 별반 차이가 없네요.
EVP_DecryptFinal() 부분은 수정했습니다. 변수를 잘못넣었네요;;
그래도 여전히 가끔씩 텍스트가 깨지는 현상이 발생하네요 ㅠ
라이브러리소스는 ubuntu 까니까 미리 깔려있던걸로 사용하고 있습니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.