1

我在下面有一些代码。我的问题是我有一个奇怪的加密和解密字符数组结尾。

#include <iostream>
#include <openssl\evp.h>

#define AES_BLOCK_SIZE 16

static EVP_CIPHER_CTX Encrypt_Context, Decrypt_Context;

int aes_init(unsigned char *key_data, int key_data_len, unsigned char *salt, EVP_CIPHER_CTX *e_ctx, 
             EVP_CIPHER_CTX *d_ctx)
{
  int i, nrounds = 1;
  unsigned char key[16], iv[16];

  i = EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), salt, key_data, key_data_len, nrounds, key, iv);
  if (i != 16) {
    printf("Key size is %d bits - should be 128 bits\n", i);
    return -1;
  }

  EVP_CIPHER_CTX_init(e_ctx);
  EVP_EncryptInit_ex(e_ctx, EVP_aes_128_cbc(), NULL, key, iv);
  EVP_CIPHER_CTX_init(d_ctx);
  EVP_DecryptInit_ex(d_ctx, EVP_aes_128_cbc(), NULL, key, iv);

  return 0;
}

unsigned char *aes_encrypt(EVP_CIPHER_CTX *e, unsigned char *plaintext, int *len)
{
  int c_len = *len + AES_BLOCK_SIZE, f_len = 0;
  unsigned char *ciphertext = (unsigned char *)malloc(c_len);
  EVP_EncryptInit_ex(e, NULL, NULL, NULL, NULL);
  EVP_EncryptUpdate(e, ciphertext, &c_len, plaintext, *len);
  EVP_EncryptFinal_ex(e, ciphertext+c_len, &f_len);
  *len = c_len + f_len;
  return ciphertext;
}

unsigned char *aes_decrypt(EVP_CIPHER_CTX *e, unsigned char *ciphertext, int *len)
{
  int p_len = *len, f_len = 0;
  unsigned char *plaintext = (unsigned char*)malloc(p_len);
  EVP_DecryptInit_ex(e, NULL, NULL, NULL, NULL);
  EVP_DecryptUpdate(e, plaintext, &p_len, ciphertext, *len);
  EVP_DecryptFinal_ex(e, plaintext+p_len, &f_len);
  *len = p_len + f_len;
  return plaintext;
}

void main()
{
    unsigned char * data_to_encrypt = (unsigned char*)"aaaaaaaaabbbbbbbbbbbbbbccccccccc";
    unsigned char *key_data = (unsigned char *)"aaaaaaaaaaaaaaaa";
    int key_data_len = strlen((const char*) key_data);
    char * ciphertext;
    char * plaintext;

    aes_init(key_data, 16, NULL, &Encrypt_Context, &Decrypt_Context);

    int length = strlen((const char*) data_to_encrypt)-1;

    printf("Clear text :%s\n", data_to_encrypt);

    ciphertext = (char *)aes_encrypt(&Encrypt_Context, data_to_encrypt, &length);
    printf("Crypted text :%s\n", ciphertext);

    plaintext = (char *)aes_decrypt(&Decrypt_Context, (unsigned char*)ciphertext, &length);
    printf("Decrypted text :%s\n", plaintext);
}

使用此代码,我进入控制台:

明文:aaaaaaaaabbbbbbbbbbbbcccccccccc 加密文本:°ЁТ☼#єз▬├^^,♦Ёфм:ЇъШ╙y╒КzukЩu@8¤════════════════════解密¤ aaaaaaaabbbbbbbbbbbbbbcccccccc☺¤¤¤¤</p>

什么是加密文本末尾的═══════════════¤¤¤¤和解密末尾的☺¤¤¤¤?我的代码有什么问题?

谢谢!

4

3 回答 3

3

加密例程处理二进制数据,而不是 C 字符串,它们返回指针的数组不是以空字符结尾的,因此当使用printf(期望以空字符结尾的字符串)打印时,您会得到随机垃圾,恰好是位于这些阵列之后。

要解决这个问题,请确保空终止,使用类似fwrite或迭代字符以打印数组。

于 2012-05-18T17:00:05.127 回答
3

ciphertext并且plaintext不是 C 风格的字符串。它们只是指向 s 数组的指针unsigned char。in 中的%s说明符printf需要一个以 null 结尾的字符串才能打印。你有两个选择:

  • 确保ciphertextplaintext都以空值结尾
  • 循环遍历数组(因为您知道它们的长度)并单独打印每个字符

通常,密码学中的所有此类字节字符串都使用十六进制,因此,使用后者可能会更好。

于 2012-05-18T17:01:04.423 回答
0

大多数加密算法会在加密之前填充数据,以确保无法从加密消息的确切长度中推断出信息。一些工具甚至在加密数据之前添加压缩(然后是填充)。

因此,一长串统一字符很可能是填充。

其余的可能意味着您看到了一些未初始化的数据。这意味着您提供的缓冲区在实际消息之后没有填充零,因此您可能会一路加密垃圾。或者,在解密时,您不会在解密数据停止时以零终止您期望的字符串。

于 2012-05-18T17:05:18.060 回答