본문 바로가기

Tech

[OpenSSL] AES 암호화 복호화

코드부터 보자.

 

 

void PrintByteBuffer(const char *strName, unsigned char *bData, int size)
{
	puts("");
	puts(strName);
	for (int i = 0; i < size; i++)
	{
		printf("%02x ", bData[i]);
		if (i % 16 == 15)		puts("");
	}
	puts("---------------------------------------");
}


void AESEncodingDecoding()
{
	SHA256_CTX		c;
	AES_KEY			aes_key = {0};
	unsigned char	in[64];
	unsigned char	out[64];
	unsigned char	restore[64];
	int				seed = time(NULL);
	const char		*key = "This is my AES key by tebek... "\
						   "One Little Two Little Three Little Endian? Indian!";
	unsigned char	m[SHA256_DIGEST_LENGTH];
	unsigned char	iv[SHA256_DIGEST_LENGTH];
	unsigned char	iv2[SHA256_DIGEST_LENGTH];

	
	// Generate symmetric key 
	SHA256_Init(&c);
	SHA256_Update(&c, key, strlen(key));
	SHA256_Final(m, &c);
	OPENSSL_cleanse(&c, sizeof(c));

	// Generate iv
	SHA256_Init(&c);
	SHA256_Update(&c, "IV test 1", 9);
	SHA256_Final(iv, &c);
	OPENSSL_cleanse(&c, sizeof(c));

	srand(seed);
	memcpy(iv2, iv, SHA256_DIGEST_LENGTH);
	
	// fill input data randomly
	for (int i = 0; i < 64; i+=2)	*(short *)(in+i) = rand();

	// Encrypt
	AES_set_encrypt_key(m, SHA256_DIGEST_LENGTH * 8, &aes_key);
	AES_cbc_encrypt(in, out, 64, &aes_key, iv, AES_ENCRYPT);
	
	// Decrypt
	AES_set_decrypt_key(m, SHA256_DIGEST_LENGTH * 8, &aes_key);
	AES_cbc_encrypt(out, restore, 64, &aes_key, iv2, AES_DECRYPT);

	// Display Result
	PrintByteBuffer("in", in, 64);
	PrintByteBuffer("out", out, 64);
	PrintByteBuffer("restore", restore, 64);

	if (memcmp(in, restore, 64) == 0)	puts("AES Test Successed !");
	else								puts("AES Test Failed !");
}

 

 

AES 암호화의 촛점은 AES_KEY를 세팅하는 것과 IV가 필요하면 세팅하는 것이다.

OpenSSL의 대칭키 암호화 키 세팅은 각각 존재하는 반면에 대칭키 암호화는 인트립트 함수 하나만 제공하고 

암호화냐 복호화냐를 파라메터로 넘겨준다. (AES_ENCODE, AES_DECODE)

 

key를 세팅할때 특이한 것은 size 파라메터로 비트수를 넘겨준다는 것이다.

function prototype에도 bits로 명시되어 있으니 이것도 조심해서 바이트를 넣지 않도록 하면 된다.

 

AES Key나 IV는 해쉬값을 이용하여 만드는 것이 안전하다.

예제에서는 PADDING이 없으나 CBC 모드에서는 padding을 해줘야 한다.

 

결과는 다음과 같다.

 

 

데이터는 random값을 생성했기 때문에 실행시마다 다를것이다.

 

테스트를 해볼 수 있는 전체 소스는 GitHub에 있다.

 

https://github.com/tebeknet/TestOpenSSL