最近工作上填了一个坑,关于C语言调用openssl是AES加解密接口解python的加密文件,遇到无法解密的问题。在这里做一个总结,以备后面自己又忘记踩过的坑。
首先了解下python的AES CFB模式加密实现方式如下,这里key的长度取决于给定的key值,总体而言python实现aes加密是真简单。
from Crypto.Cipher import AES
# 定义密钥和IV
key = b'0123456789abcdef'
iv = b'fedcba9876543210'
# 定义明文和加密器
plaintext = b'This is a secret message.'
cipher = AES.new(key, AES.MODE_CFB, iv)
# 对明文进行加密
ciphertext = cipher.encrypt(plaintext)
# 输出加密结果(这里可以改为输出到文件)
print(ciphertext)
用C实现AES CFB模式的加解密过程如下,主要是调用aes.h头文件,需要注意的点在代码的注释中说明:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#define AES_BLOCK_SIZE 16
void aes_encrypt_cfb(unsigned char *in, unsigned char *out, int length, unsigned char *key, unsigned char *iv) {
int num = 0;
AES_KEY aes_key;
AES_set_encrypt_key(key, 128, &aes_key);
AES_cfb8_encrypt(in, out, length, &aes_key, iv, &num, AES_ENCRYPT);
}
void aes_decrypt_cfb(unsigned char *in, unsigned char *out, int length, unsigned char *key, unsigned char *iv) {
int num = 0;
AES_KEY aes_key;
// 注意点:解密也使用AES_set_encrypt_key接口,第二个入参是表示密码的长度,当前密码是16Byte(128bit),如果是32Byte则填写256.
AES_set_encrypt_key(key, 128, &aes_key);
AES_cfb8_encrypt(in, out, length, &aes_key, iv, &num, AES_DECRYPT);
}
int main() {
// 密码长度由AES_set_encrypt_key函数的第二个入参决定
unsigned char key[] = "0123456789abcdef";
// iv 长度通常是16个字节
unsigned char iv[] = "1234567890abcdef";
unsigned char iv1[] = "1234567890abcdef";
unsigned char plaintext[] = "Hello, world!";
int plaintext_len = strlen(plaintext);
unsigned char ciphertext[plaintext_len];
aes_encrypt_cfb(plaintext, ciphertext, plaintext_len, key, iv);
printf("Ciphertext: ");
for (int i = 0; i < plaintext_len; i++) {
printf("%02x", ciphertext[i]);
}
printf("\n");
unsigned char decryptedtext[plaintext_len];
// iv在加密时使用之后内部值会变,所以得使用iv1,通常长度是16字节
aes_decrypt_cfb(ciphertext, decryptedtext, plaintext_len, key, iv1);
printf("Decrypted text: %s\n", decryptedtext);
return 0;
}
坑的地方:
另外关于AES的CFB模式再有问题,可以留言我们再讨论,这里我没有展开深入研究了,以后有机会再展开。