我使用OpenSSL的EVP接口使用GCM模式实现AES加密。
现在,GCM是一种身份验证模式,可提供密文完整性。这意味着它会在密文上生成一个标记(MAC - 消息认证代码)(以及其他数据,如果提供的话)。稍后可以在解密之前检查此标记,以确保密文未被修改。
我已根据此博文实施加密: http://incog-izick.blogspot.in/2011/08/using-openssl-aes-gcm.html
解密时我正在使用以下API调用(按此顺序):
// setting cipher, key and iv
EVP_DecryptInit (ctx, EVP_aes_128_gcm(), key, iv);
// setting tag
EVP_CIPHER_CTX_ctrl (ctx, EVP_CTRL_GCM_SET_TAG, taglength, tagbuffer);
// adding Additional Authenticated Data (AAD)
EVP_DecryptUpdate (ctx, NULL, &length, aad, aadlength);
// decrypting data
EVP_DecryptUpdate (ctx, decrypteddata, &length, encrypteddata, encryptedlength);
// authentication step
EVP_DecryptFinal(ctx, outbuffer, &length);
问题在于,如果我修改密文或AAD,密文仍然会被解密,并且在解密过程的最后调用中,即在EVP_DecryptFinal的调用中检测到错误。返回零值表示错误。
在我看来,错误应该抛在EVP_DecryptUpdate调用本身,解密应该失败。迟到的错误检测违背了Authenticated Encryption的目的。
这里有什么问题?
答案 0 :(得分:3)
如何知道MAC在到达密文末尾之前会失败?流式API需要在知道它已到达结束之前生成输出。
要避免这种情况,请将整个邮件解密为临时缓冲区,并且只有在您使用生成的纯文本解密后才能解密。有些API(例如NaCl的unbox
)只有在验证后才会给你密文,但那些不支持流媒体使用。
或者,您可以创建一个新的加密方案,将MAC定期放入密文,这样您就可以解密并验证这些较小的块。普通的AES-GCM还不够。