1

以下にいくつかのコードがあります。暗号化および復号化されたchar配列の奇妙な結末があるという私の問題。

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

このコードで私はコンソールに入ります:

クリアテキスト:aaaaaaaaabbbbbbbbbbbbbbccccccccc暗号化されたテキスト:°ЁТ☼#єз▬├^^、♦Ёфм:ЇъШ╙y╒КzukЩu@8¤===============¤¤¤¤復号化されたテキスト: aaaaaaaaabbbbbbbbbbbbbbcccccccc☺¤¤¤¤</p>

暗号化されたテキストの最後の===============¤¤¤¤と復号化された最後の☺¤¤¤¤とは何ですか?私のコードの何が問題になっていますか?

ありがとう!

4

3 に答える 3

3

暗号化ルーチンは、C文字列ではなく、バイナリデータを処理します。ポインタを返す配列は、nullで終了していません。そのため、printf(nullで終了する文字列を想定している)を使用して印刷すると、ランダムなガベージが発生します。これらのアレイの直後にあります。

これを解決するには、nullで終了するかfwrite、配列を印刷するために文字のようなものを使用するか、文字を繰り返し処理します。

于 2012-05-18T17:00:05.127 に答える
3

ciphertextplaintextCスタイルの文字列ではありません。これらは、unsigned charsの配列への単なるポインタです。の%s指定子はprintf、印刷するためにnullで終了する文字列を必要とします。2つの選択肢があります。

  • ciphertextとの両方plaintextがnullで終了していることを確認してください
  • 配列をループして(長さがわかっているので)、各文字を個別に印刷します

通常、暗号化におけるこのようなバイト文字列はすべて16進数を使用するため、おそらく後者の方が適しています。

于 2012-05-18T17:01:04.423 に答える
0

ほとんどの暗号化アルゴリズムは、暗号化されたメッセージの正確な長さから情報を推測できないようにするために、暗号化の前にデータをパディングします。一部のツールでは、データを暗号化する前に圧縮を追加します(その後にパディングが続きます)。

したがって、均一な文字の長い文字列はおそらくパディングです。

残りは、初期化されていないデータが表示されることを意味している可能性があります。つまり、指定したバッファは実際のメッセージの後にゼロで埋められないため、途中でガベージを暗号化している可能性があります。または、復号化するときに、復号化されたデータが停止した時点で、文字列であると予想されるものをゼロで終了しません。

于 2012-05-18T17:05:18.060 に答える