C语言 AES CBC 128 PCSKPadding7 解密问题?

老师们好:

下面是一段C 语言结合openssl库做 AES CBC 128 PCSKPadding7 加密, 加密的部分是可以, 解密是总是出现乱码。请老师们帮忙给看看:

程序输出如下:

Ciphertext (Base64): O4SkNWTfpKVOSrvpdcwbXg==
Decrypted text: :▒▒1aٞ▒tp▒▒L▒$b;▒▒5dߤ▒NJ▒▒u▒

代码如下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/buffer.h>

// PKCS7Padding填充函数
int pkcs7padding(unsigned char *data, int len, int block_size) {
    int pad_len = block_size - (len % block_size);
    for (int i = 0; i < pad_len; i++) {
        data[len + i] = pad_len;
    }
    return len + pad_len;
}

// PKCS7Padding去除填充函数
int pkcs7unpadding(unsigned char *data, int len) {
    int pad_len = data[len - 1];
    return len - pad_len;
}

// AES CBC加密函数
void aes_cbc_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key,
                     unsigned char *iv, unsigned char *ciphertext) {
    AES_KEY aes_key;
    AES_set_encrypt_key(key, 128, &aes_key);
    AES_cbc_encrypt(plaintext, ciphertext, plaintext_len, &aes_key, iv, AES_ENCRYPT);
}

// AES CBC解密函数
void aes_cbc_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key,
                     unsigned char *iv, unsigned char *plaintext) {
    AES_KEY aes_key;
    AES_set_decrypt_key(key, 128, &aes_key);
    AES_cbc_encrypt(ciphertext, plaintext, ciphertext_len, &aes_key, iv, AES_DECRYPT);
}

// Base64编码函数
char* base64_encode(const unsigned char* input, int length) {
    BIO *bio, *b64;
    BUF_MEM *bufferPtr;

    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new(BIO_s_mem());
    bio = BIO_push(b64, bio);

    // 忽略换行符
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);

    BIO_write(bio, input, length);
    BIO_flush(bio);
    BIO_get_mem_ptr(bio, &bufferPtr);

    char *output = (char*)malloc(bufferPtr->length + 1);
    memcpy(output, bufferPtr->data, bufferPtr->length);
    output[bufferPtr->length] = '\0';

    BIO_free_all(bio);
    return output;
}

// Base64解码函数
unsigned char* base64_decode(const char* input, int length, int* decoded_length) {
    BIO *bio, *b64;
    unsigned char *buffer = (unsigned char*)malloc(length);
    memset(buffer, 0, length);

    b64 = BIO_new(BIO_f_base64());
    bio = BIO_new_mem_buf((void*)input, length);
    bio = BIO_push(b64, bio);

    // 忽略换行符
    BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);

    int decoded_len = BIO_read(bio, buffer, length);

    BIO_free_all(bio);

    *decoded_length = decoded_len;
    unsigned char* output = (unsigned char*)malloc(decoded_len + 1);
    memcpy(output, buffer, decoded_len);
    output[decoded_len] = '\0';

    free(buffer);
    return output;
}

int main() {
    unsigned char key[16] = "0000000000123456";  // 128位密钥
    unsigned char iv[16] = "0000000000123456";   // 初始向量

    unsigned char plaintext[] = "123456";
    int plaintext_len = strlen((char *)plaintext);

    // 计算填充后的长度
    int padded_len = pkcs7padding(plaintext, plaintext_len, 16);

    unsigned char ciphertext[padded_len];
    unsigned char decrypted_text[padded_len];

    // 加密
    aes_cbc_encrypt(plaintext, padded_len, key, iv, ciphertext);

    // Base64编码
    char* base64_encoded = base64_encode(ciphertext, padded_len);

    printf("Ciphertext (Base64): %s\n", base64_encoded);

    // Base64解码
    int decoded_len;
    unsigned char* decoded_ciphertext = base64_decode(base64_encoded, strlen(base64_encoded), &decoded_len);

    // 解密
    aes_cbc_decrypt(decoded_ciphertext, decoded_len, key, iv, decrypted_text);

    // 去除填充字节
    int decrypted_len = pkcs7unpadding(decrypted_text, decoded_len);

    decrypted_text[decrypted_len] = '\0';

    printf("Decrypted text: %s\n", decrypted_text);

    free(base64_encoded);
    free(decoded_ciphertext);

    return 0;
}
阅读 3.3k
1 个回答
✓ 已被采纳
// 解密前重新设置IV
unsigned char decrypt_iv[16] = "0000000000123456";

// 解密
aes_cbc_decrypt(decoded_ciphertext, decoded_len, key, decrypt_iv, decrypted_text);

// 去除填充字节
int pad_len = decrypted_text[decoded_len - 1];
int decrypted_len = decoded_len - pad_len;

// 检查填充是否正确
for (int i = 0; i < pad_len; i++) {
    if (decrypted_text[decrypted_len + i] != pad_len) {
        printf("Padding error\n");
        return -1;
    }
}

decrypted_text[decrypted_len] = '\0';
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进