java - 分解 RSA/ECB/OAEPWithSHA-256AndMGF1Padding

标签 java encryption cryptography rsa

Java 有一个名为 RSA/ECB/OAEPWithSHA-256AndMGF1Padding 的模式。这到底是什么意思?

RFC3447公钥加密标准 (PKCS) #1:RSA 加密规范版本 2.17.1.2 解密操作部分说 Hash 和 MGF 都是 RSAES-OAEP 的选项-解密。 MGF 是它自己的函数,在B.2.1 节 MGF1 中定义,它也有自己的哈希“选项”。

也许 RSAES-OAEP-DECRYPT 和 MGF1 中的哈希“选项”应该是相同的,或者它们可能不是,我不清楚。如果是,那么我想当您拥有 RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING 时,这意味着 sha256 应该用于两者。但是,如果它们不应该相同,那么您可以将 sha256 用于 RSAES-OAEP-DECRYPT,例如,将 sha1 用于 MGF1。如果是这样,那么 sha256 应该用于什么功能?其他函数应该使用什么哈希算法?

在这种情况下,ECB 意味着什么? ECB 是一种对称 block 密码模式。电子密码本。也许这应该意味着 Java 如何处理大于模数的明文?就像也许将明文拆分成与模数一样大的 block ,然后用 RSA 加密每个 block 并将它们连接在一起?我只是猜测..

最佳答案

OAEP 的默认设置是对 MGF1 使用 SHA-1(但请参阅此答案末尾的编辑)。请注意,选择的哈希值对 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”,代码将失败并出现与填充相关的异常。

完全需要扩展算法的原因是与其他Cipher 算法的兼容性。为例如编写的代码"RSA/ECB/PKCS1Padding" 不使用任何参数,更不用说 OAEP 参数了。因此,如果没有更长的字符串,OAEP 将无法作为替代品。


操作模式 “ECB” 在此上下文中没有任何意义,它应该是 “None” 或者应该完全忽略。您只能使用 SunRSA 提供程序的 RSA 实现来加密单个 block 。

如果您想加密更多数据,请创建一个随机 (AES) 对称 key 并使用 OAEP 对其进行加密。然后使用 AES key 加密您的特定数据。这称为混合密码系统,因为它使用非对称和对称原语来加密数据。


请注意,JDK 7 (1.7) 或更早版本不支持 OAEP。从 Java 8 开始,OAEP 被包含在 Java 运行时的实现要求中:

  • RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
  • RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)

某些协议(protocol)可能要求您在填充中使用 SHA-256 或 SHA-512,因为 SHA-1 在大多数情况下已被弃用 - 即使它不会直接受到此类用途的攻击。<​​/p>


编辑:这主要是为 Java 编写的。到目前为止,许多其他库似乎采取了一些不同的方法,并为(大部分为空的)标签和 MGF1 使用相同的哈希值。如果您有无效的 OAEP 密文,您应该首先确保使用了正确的“默认值”。选择自己的默认值是不可能错误的任何库实现;最后,由协议(protocol)来定义所使用的哈希值。不幸的是,不存在强制性默认值 - 如果协议(protocol)所有者忘记为算法完全指定配置,这尤其是一个问题。

关于java - 分解 RSA/ECB/OAEPWithSHA-256AndMGF1Padding,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32161720/

相关文章:

Java:如何使多播IP InetAddress独占?

java - 使 Web 应用程序使用 UTF-8

c - 通过 C 中的文件使用 crypt 函数进行身份验证(段错误)

encryption - RSA 加密输出大小

java - 如何从扫描仪读取字符串,并将每个字母转换为不同的值?

c# - 使用C#进行AES解密

Python 和密码学 : md5

java - Libgdx 将 Sprite 添加到数组并将它们绘制到屏幕上

java - 处理 2 - 线程会加速渲染许多对象吗?

.net - 在 .NET 核心中实现 RSA