在IOS中使用带有openssl evp接口的aes gcm解密数据

时间:2014-11-10 08:19:00

标签: ios encryption openssl aes-gcm evp-cipher

我有以下用于解密数据的代码:

-(NSString*)_decrypte:(NSString*)encrypted
{
    NSString *decrypted;

    NSData *enc = [[NSData alloc]initWithBase64EncodedString:encrypted options:0];
    int len = (int)[enc length];
    Byte *cipher = (Byte*)malloc(len);
    memcpy((void *)cipher, [enc bytes], len);

    Byte *iv = toIv(_ivCounter++, 16);
    for(uint i = 0; i < 16; i++)
    {
        iv[i] = 0;
    }

    int outLen, plainttext_len, dec_success, tag_len = 128 / 8;
    unsigned char *plaintext = (unsigned char*)malloc(len);
    unsigned char *tag =(unsigned char*)malloc(tag_len);
    int offset = len - (tag_len);
    for(int i = 0; i < tag_len; i++)
    {
        tag[i] = cipher[i + offset];
    }

    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (void *)tag);
    EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL);
    EVP_DecryptInit_ex(ctx, NULL, NULL, _sesKey, iv);
    EVP_DecryptUpdate(ctx, NULL, &len, NULL, 0);
    EVP_DecryptUpdate(ctx, plaintext, &outLen, cipher, len);
    plainttext_len = outLen;
    dec_success = EVP_DecryptFinal_ex(ctx, plaintext + outLen, &outLen);
    EVP_CIPHER_CTX_free(ctx);

    decrypted = [NSString stringWithFormat:@"%s", plaintext];

    return decrypted;
}

由于某种原因,代码没有正确解密数据。 _sesKey是正确的,并且在调用toIV之后覆盖IV以强制对第一组数据执行右iv,并且不需要解密所需的AAD数据。我已经在android(使用bouncycastle库)中完成了这个,所以我知道_sesKey和IV是正确的。我不知道是否有人可以通过告诉我出了什么问题以及为什么来帮助我。

1 个答案:

答案 0 :(得分:0)

我在一些帮助下发现了错误,问题是变量_sesKey是一个指针,在生成密钥和解密数据期间,指针指向的内存被扯掉了。所以_sesKey变得无效。所以现在将_sesKey更改为正常的字节数组,现在它可以正常工作。