使用C语言调用libcrypto.so实现AES的CFB模式文件加解密

最近工作上填了一个坑,关于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 
#include 
#include 
#include 

#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;
}

坑的地方:

  1. 在于aes.h中加密接口有三个AES_cfb128_encrypt,AES_cfb8_encrypt, AES_cfb1_encrypt,不知道选择哪个是和python加密的对应的。
  2. 一般理解设置加密使用AES_set_encrypt_key进行密钥设置,解密应该使用AES_set_decrypt_key设置解密密钥,这就是坑,解密也要使用AES_set_encrypt_key设置密钥。
  3. 密钥的长度单位是bit,注意看python的是128bit还是256bit,在AES_set_encrypt_key的第二个入参需要给正确

另外关于AES的CFB模式再有问题,可以留言我们再讨论,这里我没有展开深入研究了,以后有机会再展开。

你可能感兴趣的:(笔记,解决问题,经验分享,c语言,加密,openssl,python,linux)