openssl 을 활용한 AES-CTR (key, IV)
reference: https://www.openssl.org/docs/manmaster/man3/EVP_EncryptInit_ex.html
#include <string.h>
#include <glib.h>
#include <openssl/aes.h> //for AES_BLOCK_SIZE
#include <openssl/err.h> //for ERR_error_string()
#include <openssl/evp.h>
static gboolean encrypt_data_by_aes_ctr (guint8 **out_data,
gint *out_data_len,
guint8 *in_data,
gint in_data_len,
guint8 *key,
guint8 *iv)
{
gboolean ret = FALSE;
EVP_CIPHER_CTX *ctx = NULL;
gint c_len, f_len;
guint8 *ciphertext;
g_assert_nonnull (out_data);
g_assert_nonnull (in_data);
g_assert_nonnull (key);
g_assert_nonnull (iv);
c_len = in_data_len + AES_BLOCK_SIZE;
f_len = 0;
ctx = EVP_CIPHER_CTX_new ();
ciphertext = g_malloc (c_len);
EVP_EncryptInit_ex (ctx, EVP_aes_128_ctr (), NULL, key, iv);
if (EVP_EncryptUpdate (ctx, ciphertext, &c_len, in_data, in_data_len) == 0) {
g_error ("fail EVP_EncryptUpdate: %s",
ERR_error_string (ERR_peek_last_error (), NULL));
g_free (ciphertext);
goto exit;
}
if (EVP_EncryptFinal_ex (ctx, ciphertext + c_len, &f_len) == 0) {
g_error ("fail EVP_EncryptFinal_ex: %s",
ERR_error_string (ERR_peek_last_error (), NULL));
g_free (ciphertext);
goto exit;
}
*out_data = ciphertext;
*out_data_len = c_len + f_len;
ret = TRUE;
exit:
EVP_CIPHER_CTX_free (ctx);
return ret;
}
static gboolean encrypt_data_by_aes_ctr_with_keying_data (guint8 **out_data,
gint *out_data_len,
guint8 *in_data,
gint in_data_len,
guint8 *key_data,
gint key_data_len)
{
gboolean ret = FALSE;
gint ret_openssl;
guint8 key_gen[16], iv_gen[16];
ret_openssl = EVP_BytesToKey (EVP_aes_128_ctr (), EVP_sha1 (), NULL,
key_data, key_data_len, 0, key_gen, iv_gen);
if (ret_openssl != 16) {
g_error ("Key size is %d bytes - should be 16 bytes", ret_openssl);
goto exit;
}
ret = encrypt_data_by_aes_ctr (out_data, out_data_len,
in_data, in_data_len, key_gen, iv_gen);
exit:
return ret;
}
static gboolean decrypt_data_by_aes_ctr (guint8 **out_data,
gint *out_data_len,
guint8 *in_data,
gint in_data_len,
guint8 *key,
guint8 *iv)
{
gboolean ret = FALSE;
EVP_CIPHER_CTX *ctx = NULL;
gint p_len, f_len;
guint8 *plaintext;
g_assert_nonnull (out_data);
g_assert_nonnull (in_data);
g_assert_nonnull (key);
g_assert_nonnull (iv);
p_len = 0;
f_len = 0;
plaintext = g_malloc (in_data_len);
ctx = EVP_CIPHER_CTX_new ();
EVP_DecryptInit_ex (ctx, EVP_aes_128_ctr (), NULL, key, iv);
if (EVP_DecryptUpdate (ctx, plaintext, &p_len, in_data, in_data_len) == 0) {
g_error ("fail EVP_DecryptUpdate: %s",
ERR_error_string (ERR_peek_last_error (), NULL));
g_free (plaintext);
goto exit;
}
if (EVP_DecryptFinal_ex (ctx, plaintext + p_len, &f_len) == 0) {
g_error ("fail EVP_DecryptFinal_ex: %s",
ERR_error_string (ERR_peek_last_error (), NULL));
g_free (plaintext);
goto exit;
}
*out_data = plaintext;
*out_data_len = p_len + f_len;
ret = TRUE;
exit:
EVP_CIPHER_CTX_free (ctx);
return ret;
}
static gboolean decrypt_data_by_aes_ctr_with_keying_data (guint8 **out_data,
gint *out_data_len,
guint8 *in_data,
gint in_data_len,
guint8 *key_data,
gint key_data_len)
{
gboolean ret = FALSE;
gint ret_openssl;
guint8 key_gen[16], iv_gen[16];
ret_openssl = EVP_BytesToKey (EVP_aes_128_ctr (), EVP_sha1 (), NULL,
key_data, key_data_len, 0, key_gen, iv_gen);
if (ret_openssl != 16) {
g_error ("Key size is %d bytes - should be 16 bytes", ret_openssl);
goto exit;
}
ret = decrypt_data_by_aes_ctr (out_data, out_data_len,
in_data, in_data_len, key_gen, iv_gen);
exit:
return ret;
}
void main()
{
gint i;
gint encrypted_len;
guint8 *encrypted;
gint decrypted_len;
guint8 *decrypted;
guint8 plain[48] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, };
if (encrypt_data_by_aes_ctr_with_keying_data (&encrypted, &encrypted_len,
plain, sizeof(plain),
"key", sizeof("key"))) {
g_print ("encrypted value: ");
for (i = 0; i < encrypted_len; i++) {
g_print ("%.2X ", encrypted[i]);
}
g_print ("\n");
}
if (decrypt_data_by_aes_ctr_with_keying_data (&decrypted, &decrypted_len,
encrypted, encrypted_len,
"key", sizeof("key"))) {
g_print ("decrypted value: ");
for (i = 0; i < decrypted_len; i++) {
g_print ("%.2X ", decrypted[i]);
}
g_print ("\n");
}
g_assert_cmpmem (plain, sizeof(plain), decrypted, decrypted_len);
g_free (encrypted);
g_free (decrypted);
}
'개발자료 > Openssl' 카테고리의 다른 글
RSAES-OAEP encrypt / decrypt (0) | 2018.01.24 |
---|---|
RSASSA PKCS1 v1.5 (0) | 2018.01.24 |
HMAC-SHA256 (0) | 2018.01.24 |
SHA256 (0) | 2018.01.24 |