Authenticated Encryption should check for tag length
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 30/100
- Issue 类型
- 功能
- 描述清晰度
- 基本清楚
- 活跃度
- 停滞
- 领域
- cryptography, security
调研方向
首先追踪 AES-GCM 现有的 Cipher#auth_tag 和 #final 行为,包括当前如何引发 CipherError。检查所请求的 auth_tag_len 行为和文档要求,然后比较加密和解密路径。当 API 提案得到解决、标签长度按指定方式进行检查,并且相关行为已记录在文档中且有测试覆盖时,即视为完成。
由索引模型根据 Issue 内容生成。
描述
The current API for using ciphers with Authenticated Encryption (currently only AES-GCM) is rather misleading and quickly leads to subtle bugs related to the length of auth_tag.
In particular, the current implementation will not check for the length of the auth_tag. Because GCM mode allows arbitrary sizes of the auth_tag up to 128 bytes, only a single byte needs to be supplied to make the authentication pass. This means that an attacker needs at most 256 attempts in order to forge a valid auth_tag.
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
auth_tag = auth_tag[0] # single byte is sufficient
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
# NO error raised
Currently, the only way to prevent such attacks is to manually assert the correct auth_tag length when decrypting/authenticating.
raise 'incorrect auth_tag length' unless auth_tag.length == 16
I suggest the following improvements:
Documentation should mention the importance of manually checking auth_tag length
This can/should be done immediately even if the API should not change.
Authentication tag length should be an input parameter to the cipher
To improve the usability of the API and unburden users from performing additional manual checks without compromising security, I suggest to add an auth_tag_len accessor. This can be used to determine the size of the auth_tag both when generating and when authenticating the auth_tag. The default value should be 16 bytes (see below).
#auth_tag should use auth_tag_len to determine the output length
During encryption:
If no parameter is given, #auth_tag should return an authentication tag according to the length configured in auth_tag_len.
If a length parameter is given, #auth_tag should use the supplied parameter to determine the length of the authentication tag. Although this parameter is not as useful any more it should be kept for backwards compatibility. Maybe it should be deprecated.
Currently the API supports different tag lengths by passing the length parameter to #auth_tag. This currently defaults to 16 bytes, which should be the default value for auth_tag_len in order to keep backwards compatibility.
#final should use auth_tag_len to assert the correct length of the auth_tag
During decryption:
auth_tag_len should be used to assert that the supplied auth_tag has the correct length. The big difference to the existing API lies here, because users need to actively change the value of auth_tag_len in order to allow shorter tags.
When the check fails, an OpenSSL::Cipher::CipherError should be raised. The same type of error is already raised when authentication fails, so existing users should be fine without having to touch their error handling. A descriptive error message should be helpful. In order to distinguish between such errors and "actual" verification errors, we could also add a descriptive message for the latter.
I'd be happy to implement these changes, but I wanted to discuss them first.
For reference: This issue was copied over from the Ruby Issue Tracker https://bugs.ruby-lang.org/issues/12582
- 主要语言
- C
- 星标
- 276
- 派生
- 200
- 平均合并
- 15 小时 35 分钟
- 30 天内合并 PR
- 7
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
ruby/openssl 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 48/100
维护者通常 1 天内回复
-
难度 5/5 一周以上 新手友好度 35/100
维护者通常 1 天内回复
-
难度 4/5 3-5 天 新手友好度 35/100
维护者通常 1 天内回复
-
难度 3/5 1-2 天 新手友好度 45/100
维护者通常 1 天内回复
相似的 Issue
-
area/ysql kind/bug priority/medium
难度 2/5 1-3 小时 新手友好度 86/100
yugabyte/yugabyte-db#34584 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 88/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 82/100
ExpressLRS/ExpressLRS#3806 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 88/100
-
难度 1/5 1 小时以内 新手友好度 88/100
维护者通常 1 天内回复