3

SecKeyEncrypt()尝试使用with时,我遇到了一些挫败感kSecPaddingNone。经过大量调查,我找到了一种解决方法,但我想知道发生了什么。目前,我没有可用的代码,但我可以在今天晚些时候发布它。不过,我真的不相信问题出在我的代码中:我倾向于相信我只是在做一些根本错误的事情。(也就是说,我相信我的代码是正确的,但我正在尝试做的是错误的。)

我的问题是:我想使用对称密钥加密一大块数据,然后使用不同的公钥加密该密钥。使用CryptoExercise作为模板,我很容易得到一堆代码。我为 生成一个对称密钥AES128,用它来加密我的大缓冲区。我的单元测试对此没有任何问题。

但是后来我的单元测试创​​建了一个公钥/私钥对,尝试用公钥加密对称密钥,用私钥解密,然后解密大缓冲区。请注意,我根据问题集的受限域做了一些简化假设:我总是AES128用来加密大缓冲区,所以密钥总是 16 字节,我总是使用 1024 位公共/私钥对,所以我AES通过创建一个 128 字节的缓冲区来加密密钥,用随机数据填充它,然后将AES密钥嵌入到该缓冲区中。

最后,由于我有一组固定的缓冲区大小,我在kSecPaddingNone调用 `SecKeyEncrypt() 时使用。我的假设是我可以依靠我填充缓冲区的方法和缓冲区大小的知识。

当我开始运行测试时,我看到的情况令人沮丧:大约 80% 的时间,它们运行良好。但另外 20%SecKeyEncrypt()失败OSStatus,参数错误为 -50。我花了很多时间寻找堆栈损坏、堆损坏、过早释放等,但没有结果。

然后我开始在普通的旧缓冲区上查看公钥/私钥对操作,即我做了一个新的单元测试,试图加密/解密我手动创建和填充的缓冲区。至此,我找到了线索:如果我发送了,例如,一个零缓冲区,然后SecKeyEncrypt陷入了无限循环。如果我发送一个只填充一个的缓冲区,那么它工作得很好。如果我用 1 填充缓冲区,然后用零替换第一个字节,我又回到了无限循环。

各种其他模式使我找到了解决方法,目前是在第一个字节之后插入 AES 密钥并始终将第一个字节设置为一个,但我非常困惑。从文档中SecKeyEncrypt()

通常kSecPaddingPKCS1 使用 ,它PKCS1在加密之前添加填充。如果您指定kSecPaddingNone,则数据按原样加密。

我读到的方式,明文缓冲区的内容不应该影响加密算法的执行,但是,我的单元测试似乎表明它正在发生,并且缓冲区的第一个字节对操作至关重要. 而且我的解决方法似乎 100% 的时间通过了我的单元测试。

这里有更多经验的人有什么可以帮助我理解发生了什么吗?我是否误解了文档?我是否正在尝试做一些我不应该做的事情?我是否过于简单化了?

我可以在今晚晚些时候发布代码,一旦我可以再次访问它,如果有人认为它会有所帮助。

4

1 回答 1

2

当您使用原始 RSA 加密时,您的消息m(表示为整数)必须小于(公共)密钥(ne )的模数n,否则无法解密,请参阅RSA的描述算法

c = m ^ e (mod n )

填充处理了这一点,PKCS#1 等标准经过精心设计,可在 RSA 加密之前安全地填充消息。如果您要求kSecPaddingNone该功能,则假定您知道自己在做什么并提供自己的填充。

请注意,您永远不应该使用原始 RSA 加密,它始终是旨在避免算法弱点的协议的一部分,请参阅“针对普通 RSA 的攻击”。

于 2013-09-09T23:17:29.853 回答