如果我正确理解 GCM 模式,它应该不仅提供加密,还提供密文的身份验证。但是,当我使用 Ruby 的 OpenSSL 实现以 AES-256-GCM
模式加密数据时,即使我篡改了 auth_tag
,它也会愉快地解密数据。我是不是遗漏了什么,或者实现确实有问题?
require 'openssl'
# ALICE encrypts some secret data
data = 'secret'
cipher = OpenSSL::Cipher.new('aes-128-gcm')
cipher.encrypt
key = cipher.random_key
iv = cipher.random_iv
cipher.auth_data = 'auth_data'
ciphertext = cipher.update(data) + cipher.final
auth_tag = cipher.auth_tag
# EVE tampers with the auth tag, e.g. dropping the last 10 bytes
auth_tag = auth_tag[0..-11]
# BOB decrypts the ciphertext
cipher = OpenSSL::Cipher.new('aes-128-gcm')
cipher.decrypt
cipher.key = key
cipher.iv = iv
cipher.auth_tag = auth_tag
cipher.auth_data = 'auth_data'
data = cipher.update(ciphertext) + cipher.final
# BOB is very sad because no error is raised!
我正在使用内置 OpenSSL 版本的 OS X:
% openssl version
OpenSSL 0.9.8zg 14 July 2015
最佳答案
GCM 支持身份验证标签的多种尺寸。在这些版本中,通过从右侧删除字节来缩短身份验证标记。这正是您的攻击者似乎正在做的事情。
现在 API 非常不稳定。首先,(16 - 10) * 8 = 48,不是 AES-GCM 的有效大小(根据 NIST SP 800-38D )。此外,身份验证标签大小应该是输入或配置密码的参数。至少 API 应该警告用户自己检查身份验证标签大小,而不是只允许输入任何身份验证标签。
所以是的,您遗漏了一些东西并且是的,我会说实现 - 或者至少是文档 - 被破坏了;好收获。
关于ruby - AES-128-GCM 似乎不检查身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38293211/