繁体   English   中英

为什么使用EVP进行加密/解密时aes_128_cbc()可以工作,而aes_128_gcm()却不起作用?

[英]Why does aes_128_cbc() work but not aes_128_gcm() for encryption/decryption using EVP?

下面的代码使用aes_128_cbc并正确加密了代码,但是当我将其更改为aes_128_gcm时,没有加密的输出。下面的代码是我的原始工作代码。 我的密钥是128位(长度16),并且iv也是长度16。

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


    EVP_CIPHER_CTX *ctx;
    char key[]="somerandomkey123"; /*length 16*/
    char output[1024];
    char input[]= "Message here.";
    int len;
    FILE *binfile;


    if(!ctx = EVP_CIPHER_CTX_new()){
        (error message)
    }
    if(1 != EVP_EncryptInit_ex(ctx,EVP_aes_128_cbc(),NULL,key,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\")){
        (error message)
    }
    if(1 != EVP_EncryptUpdate(ctx,output,&len,input,strlen(input))){
        (error message)
    }
    if(1 != EVP_EncryptFinal_ex(ctx, output+len, &len)){
        (error message)
    }

    EVP_CIPHER_CTX_free(ctx)

    /*This prints out 0 when I change cbc to gcm, but prints a correct    size when I use cbc*/
    printf("Output size: %d \n", len);

    /*Properly writes to file when cbc used but not when gcm used. Nothing is in encrypted.bin when gcm is used when encrypted text should be there.*/
    binfile = fopen("encrypted.bin","wb");
    fwrite(outbuf,len,1,binfile);

当我将EVP_aes_128_cbc()更改为EVP_aes_128_gcm()时,代码不再起作用。 我还将iv的长度更改为12(“ \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0 \\ 0”)。 最后,我在EVP_EncryptFinal_ex之后添加了以下代码块:

    char tag[] = "1234567890123456";

    if(1 != EVP_CIPHER_CTX_ctrl(ctx,EVP_CTRL_GCM_GET_TAG,16,tag)){
        (error message)
    }

我的最终输出在打印时大小为0,并且其中没有任何内容(原始代码中已注明)。 我的问题是,当我仅将cbc更改为gcm时,为什么我没有得到任何加密? 是由于密钥/ IV大小问题引起的还是更大的?

EncryptUpdate和EncryptFinal都添加到输出缓冲区(或不添加到输出缓冲区)。 对于您的短纯文本消息,在CBC模式下,所有输出均由EncryptFinal编写,而在GCM模式下,所有输出均由EncryptUpdate编写。

您的代码中的问题是事实,您正在EncryptUpdate和EncryptFinal中重用“ len”变量。 它们都通过调用添加的数据量来(覆盖)len。 因此,在CBC模式下,EncryptFinal用16覆盖初始的0,而在GCM模式下,用0覆盖初始的13。

您应该按照openssl Wiki( https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption )中的说明进行操作:

/* Provide the message to be encrypted, and obtain the encrypted output.
 * EVP_EncryptUpdate can be called multiple times if necessary
 */
if(1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len))
  handleErrors();
ciphertext_len = len;

/* Finalise the encryption. Further ciphertext bytes may be written at
 * this stage.
 */
if(1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) 
  handleErrors();
ciphertext_len += len;

顺便说一句:您可以继续使用strlen作为输入数据的长度(如果仅是文本),但是请记住,这不会加密零终止符,因此解密后必须手动添加它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM