AES GCM/CTR 相同的输出
AES GCM/CTR same output
我正在尝试使用 AES-GCM。我的加密代码有效,但是当我尝试使用相同的 IV 和密钥加密相同的纯文本时,我得到了相同的结果。我的 GCM 代码:
EVP_CIPHER_CTX *ctx;
int outlen, tmplen;
unsigned char outbuf[1024];
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(gcm_iv), NULL);
EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv);
EVP_EncryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad));
EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt));
printf("Ciphertext:\n");
BIO_dump_fp(stdout, outbuf, outlen);
EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, outbuf);
printf("\n\n\n");
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(gcm_iv), NULL);
EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv);
EVP_EncryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad));
EVP_EncryptUpdate(ctx, outbuf2, &outlen2, gcm_pt, sizeof(gcm_pt));
printf("Ciphertext:\n");
BIO_dump_fp(stdout, outbuf2, outlen2);
EVP_EncryptFinal_ex(ctx, outbuf2, &outlen2);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, outbuf2);
EVP_CIPHER_CTX_free(ctx);
如果在第二次加密时我将init_ex、ctx_ctrl等去掉,我的密文将是一个空字符串。
但是如果我使用EVP_aes_256_ctr,那么下一次加密会给我新的密文。 EVP_aes_256_ctr 的代码:
EVP_CIPHER_CTX *ctx;
int outlen, tmplen;
unsigned char outbuf[1024];
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(gcm_iv), NULL);
EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv);
EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt));
BIO_dump_fp(stdout, outbuf, outlen);
EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
printf("\n\n\n");
EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt));
printf("Ciphertext:\n");
BIO_dump_fp(stdout, outbuf, outlen);
EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
EVP_CIPHER_CTX_free(ctx);
据我了解,这两种模式都在计数器模式下工作,因此计数器将为相同的 IV、密钥、明文生成不同的密码。那么为什么在GCM模式下密文是一样的呢?
如果你 运行 算法两次使用相同的输入,你将得到相同的输出。如果您想多次加密同一个明文并且不让攻击者看到它是相同的,请使用不同的 IV。如果你想在明文中重复一个块并且不让攻击者推断出模式,你不想重新启动。请注意,在有效的示例中,您如何在 调用 EVP_EncryptUpdate()
之前调用 EVP_EncryptInit_ex()
,而在无效的示例中,您调用了 EVP_EncryptInit_ex()
再次 在 他们之间。
我正在尝试使用 AES-GCM。我的加密代码有效,但是当我尝试使用相同的 IV 和密钥加密相同的纯文本时,我得到了相同的结果。我的 GCM 代码:
EVP_CIPHER_CTX *ctx;
int outlen, tmplen;
unsigned char outbuf[1024];
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(gcm_iv), NULL);
EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv);
EVP_EncryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad));
EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt));
printf("Ciphertext:\n");
BIO_dump_fp(stdout, outbuf, outlen);
EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, outbuf);
printf("\n\n\n");
EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(gcm_iv), NULL);
EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv);
EVP_EncryptUpdate(ctx, NULL, &outlen, gcm_aad, sizeof(gcm_aad));
EVP_EncryptUpdate(ctx, outbuf2, &outlen2, gcm_pt, sizeof(gcm_pt));
printf("Ciphertext:\n");
BIO_dump_fp(stdout, outbuf2, outlen2);
EVP_EncryptFinal_ex(ctx, outbuf2, &outlen2);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_GET_TAG, 16, outbuf2);
EVP_CIPHER_CTX_free(ctx);
如果在第二次加密时我将init_ex、ctx_ctrl等去掉,我的密文将是一个空字符串。
但是如果我使用EVP_aes_256_ctr,那么下一次加密会给我新的密文。 EVP_aes_256_ctr 的代码:
EVP_CIPHER_CTX *ctx;
int outlen, tmplen;
unsigned char outbuf[1024];
ctx = EVP_CIPHER_CTX_new();
EVP_EncryptInit_ex(ctx, EVP_aes_256_ctr(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, sizeof(gcm_iv), NULL);
EVP_EncryptInit_ex(ctx, NULL, NULL, gcm_key, gcm_iv);
EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt));
BIO_dump_fp(stdout, outbuf, outlen);
EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
printf("\n\n\n");
EVP_EncryptUpdate(ctx, outbuf, &outlen, gcm_pt, sizeof(gcm_pt));
printf("Ciphertext:\n");
BIO_dump_fp(stdout, outbuf, outlen);
EVP_EncryptFinal_ex(ctx, outbuf, &outlen);
EVP_CIPHER_CTX_free(ctx);
据我了解,这两种模式都在计数器模式下工作,因此计数器将为相同的 IV、密钥、明文生成不同的密码。那么为什么在GCM模式下密文是一样的呢?
如果你 运行 算法两次使用相同的输入,你将得到相同的输出。如果您想多次加密同一个明文并且不让攻击者看到它是相同的,请使用不同的 IV。如果你想在明文中重复一个块并且不让攻击者推断出模式,你不想重新启动。请注意,在有效的示例中,您如何在 调用 EVP_EncryptUpdate()
之前调用 EVP_EncryptInit_ex()
,而在无效的示例中,您调用了 EVP_EncryptInit_ex()
再次 在 他们之间。