AES 密钥的 256 字节长 RSA 加密

256 byte long RSA encryption of AES key

我正在尝试用 RSA 加密 32 个字符长度的 AES 密钥。 最终在预生成的 public 密钥和 objective-C 的 RSA 实现的帮助下成功做到了这一点: https://github.com/ideawu/Objective-C-RSA/blob/master/RSA.m

NSData *enc = [RSA encryptData:data publicKey:pubkey];

然后调用库的方法。基本上,它的作用如下:它从 public 密钥创建一个 SecKeyRef,然后计算 block_size、data_size 等。最后它调用

SecKeyEncrypt(keyRef, kSecPaddingPKCS1, srcbuf + idx, data_len, outbuf, &outlen);

我不太了解加密方法内部的情况,但结果是正确创建的加密密钥。

然后我可以在

的帮助下用 public 密钥解密它
SecKeyDecrypt(keyRef, kSecPaddingNone, srcbuf + idx, data_len, outbuf, &outlen);

结果完全正确。

但是编码后的密钥有 144 个字节长。这不是我需要的。出于某种原因,我需要密钥正好是 256 个字节。

我的第一个想法是用一些常量变量(例如 0)填充其余字节,但我认为不应该这样做。

接下来的想法是使用不同的填充。名称 kSecPaddingPKCS1SHA256 听起来像是正确的填充,但使用它而不是 kSecPaddingPKCS1 对密钥进行编码导致应用程序失败并出现错误:

SecKeyEncrypt fail. Error Code: -50

估计跟block_size有关系,但我对加密的内幕了解不多

我需要编码的密钥正好是 256 字节长,我该怎么做?

您需要使用 2048 位(即 256 字节)的 RSA 密钥来加密您的数据。在这种情况下,模数将为 256 字节,并且生成的密文 - 在这种情况下为包装密钥 - 也将具有该大小。

不需要做的是将解密的 AES 密钥作为密文的前缀 - 这没有意义。您需要做的是使用接收方的 public 密钥为 encryptedwrapped AES 密钥添加前缀.

解密后生成的 AES 密钥应再次为 256 位(即 32 字节)。


关于填充,在加密和解密过程中填充应该始终相同。目前只有 OAEP 填充被认为是安全的。如果您使用 PKCS#1 填充,则必须确保您不会受到填充 oracle 攻击。

出于同样的原因,建议使用 AES-GCM 而不是 CBC,CBC 容易受到填充 oracle 攻击。

1024 位 RSA 通常不再被认为是安全的。至少使用 2048 的密钥。