OAEP 的默认设置是将 SHA-1 用于 MGF1(但请参阅此答案末尾的编辑)。请注意,所选的哈希对OAEP的安全性没有太大影响,因此大多数情况下,它将保留此默认值。
我们可以通过测试它来轻松测试它:"OAEPPadding"
OAEPParameterSpec
// --- we need a key pair to test encryption/decryption
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024); // speedy generation, but not secure anymore
KeyPair kp = kpg.generateKeyPair();
RSAPublicKey pubkey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey privkey = (RSAPrivateKey) kp.getPrivate();
// --- encrypt given algorithm string
Cipher oaepFromAlgo = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
oaepFromAlgo.init(Cipher.ENCRYPT_MODE, pubkey);
byte[] ct = oaepFromAlgo.doFinal("owlstead".getBytes(StandardCharsets.UTF_8));
// --- decrypt given OAEPParameterSpec
Cipher oaepFromInit = Cipher.getInstance("RSA/ECB/OAEPPadding");
OAEPParameterSpec oaepParams = new OAEPParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-1"), PSpecified.DEFAULT);
oaepFromInit.init(Cipher.DECRYPT_MODE, privkey, oaepParams);
byte[] pt = oaepFromInit.doFinal(ct);
System.out.println(new String(pt, StandardCharsets.UTF_8));
如果将 MGF1 替换为参数,则代码将失败并显示与填充相关的异常。"SHA-256"
之所以需要扩展算法,是因为与其他算法兼容。编写如下代码: 不使用任何参数,更不用说 OAEP 参数了。因此,如果没有更长的字符串,OAEP就无法作为替代。Cipher
"RSA/ECB/PKCS1Padding"
在这种情况下,操作模式没有任何意义,它应该被或应该被完全排除在外。您只能使用 SunRSA 提供程序的 RSA 实现来加密单个块。"ECB"
"None"
如果要加密更多数据,请创建一个随机 (AES) 对称密钥并使用 OAEP 对其进行加密。然后使用 AES 密钥加密您的特定数据。这被称为混合密码系统,因为它使用非对称和对称基元来加密数据。
请注意,JDK 7 (1.7) 或更早版本不支持 OAEP。自 Java 8 以来,OAEP 已包含在 Java 运行时的实现要求中:
-
RSA/ECB/OAEPWithSHA-1AndMGF1Padding
(1024, 2048)
-
RSA/ECB/OAEPWithSHA-256AndMGF1Padding
(1024, 2048)
某些协议可能要求您在填充中使用 SHA-256 或 SHA-512,因为 SHA-1 在大多数用途中被弃用 - 即使它不直接容易受到此类目的的攻击。
编辑:这主要是用Java编写的。到目前为止,许多其他库似乎采取了一种有些不同的方法,并对(大部分为空的)标签和MGF1使用相同的哈希值。如果您有无效的 OAEP 密文,则应首先确保使用正确的“默认值”。任何库实现都不可能错误地选择自己的默认值;最后,由协议来定义使用的哈希值。不幸的是,不存在强制性的默认值 - 如果协议所有者忘记完全指定算法的配置,这尤其是一个问题。