java 用SHA-256和MGF 1填充破解RSA/ECB/OAEP

8gsdolmq  于 2023-01-11  发布在  Java
关注(0)|答案(1)|浏览(358)

Java有一个叫做RSA/ECB/OAEPWithSHA-256AndMGF1Padding的模式,这到底是什么意思?
RFC 3447,* 公钥加密标准(PKCS)#1:RSA密码技术规范版本2.1*,章节 *7.1.2解密操作 * 指出哈希和MGF都是RSAES-OAEP-DECRYPT的选项。MGF是其自己的函数,在 * 章节B.2.1 MGF 1 * 中定义,并且也具有其自己的哈希“选项”。
也许RSAES-OAEP-DECRYPT和MGF 1中的哈希“选项”应该是相同的,或者它们可能不是,这对我来说是不清楚的。如果它们是,那么我猜当您使用RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING时,这意味着sha 256应该用于两者。但是如果它们不应该是相同的,那么您可以将sha 256用于RSAES-OAEP-DECRYPT,例如,sha1用于MGF 1,如果是这样的话,那么sha 256应该用于什么函数,另外一个函数应该使用什么哈希算法?
ECB在这里是什么意思?ECB是一种对称的块密码模式。电子码本。也许它应该是指Java如何处理比模大的明文?比如可能把明文分成和模一样大的块,然后用RSA加密每个块,并把它们连接在一起?我只是猜测。

ovfsdjhp

ovfsdjhp1#

OAEP的默认值是对MGF 1使用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));

如果用"SHA-256"替换MGF 1作为参数,则代码将失败,并出现与填充相关的异常。
之所以需要扩展算法,是因为它与其他Cipher算法兼容。例如,为"RSA/ECB/PKCS1Padding"编写的代码不使用任何参数,更不用说OAEP参数了。因此,如果没有更长的字符串,OAEP就不能作为替换中的拖放。
操作模式"ECB"在本文中没有任何意义,它应该是"None"或者应该完全省略。您只能使用SunRSA提供程序的RSA实现加密单个块。
如果要加密更多数据,请创建一个随机(AES)对称密钥并使用OAEP对其进行加密。然后使用AES密钥加密特定数据。这称为混合加密系统,因为它同时使用非对称基元和对称基元来加密数据。
请注意,JDK 7(1.7)或更早版本不支持OAEP。从Java 8开始,OAEP包含在Java运行时的实现要求中:

  • x一个m七个n一个x(1024,2048)
  • RSA/ECB/OAEPWithSHA-256AndMGF1Padding(1024、2048)

一些协议可能要求您在填充中使用SHA-256或SHA-512,因为SHA-1在大多数情况下都不受欢迎-即使它在这类用途上没有直接的漏洞。
编辑:这本书主要是针对Java编写的。到目前为止,许多其他库似乎采取了一些不同的方法,对标签(大部分为空)和MGF 1使用相同的哈希值--这确实更有意义。如果你有一个无效的OAEP密文,你应该首先确保使用正确的“默认值”。不可能错误地选择任何库实现自己的默认值;最后,由协议来定义所使用的散列。2不幸的是,不存在强制性的默认值--如果协议所有者忘记完全指定算法的配置,这尤其是一个问题。

相关问题