javax.crypto.Cipher为RSA使用了哪个填充

我需要通过RSA解密消息,以便通过不安全的通道发送消息,但我害怕Padding Oracle Attack 。 因此我已经问过以下问题:

  1. 如何validationRSA加密消息的完整性?
  2. 如何使用javax.crypto.Cipher确保RSA密码的消息完整性

像第一个问题中建议的那样,

但是,由于您使用的是高级加密库,因此您不必担心这一点。 该图书馆的作者应该照顾它。

我不应该考虑。 据我所知, PKCS#1 v1.5的RSA实现容易受到Padding Oracale Attack ,因此OAEP不是(假设它已正确实现)

因此,我想知道Java 7的javax.crypt.Cipher使用了哪个填充实现

它取决于所选择的或默认的提供程序,当您实例化一个密码而没有完全限定它时,实际使用哪个填充:

 Cipher.getInstance("RSA") 

这样做是一种不好的做法,因为如果你切换Java实现,可能会有不同的默认值,突然间,你将不再兼容旧的密文。 始终完全符合密码。

正如我之前所说,默认可能(有许多提供商,一个不能确定)是PKCS#1 v1.5填充。 如果您需要另一个,则必须指定它。 如果您想使用OAEP,这里是一个完全限定的密码字符串:

 Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); 

在加密站点的第一个链接中,这不是一个好建议。 您永远不应该依赖加密库加密算法的默认值。 这有很多原因:

  1. 不同的实现,不同的默认值(对于默认值,加密提供程序没有要求,尽管大多数都会复制Oracle / Sun默认值);
  2. 现在安全性可能不会被认为是安全的,因为为了向后兼容,您永远不能更改默认值;
  3. 任何读软件的人都不清楚默认是什么(你可以记录它,但在这种情况下你也可以把它写出来)。

由于历史原因,Oracle提供的SunJCEProvider默认使用PKCS#1填充( "PKCS1Padding" )(参见上面的原因#2)。 这没有很好的记录。

那时设置了默认值,你基本上只有不安全的教科书RSA( "NoPadding" )和PKCS#1 v1.5版本( PKCS#1 v2.1标准中的 "PKCS1Padding"RSAES-PKCS1-v1_5 )。 那时RSAES-PKCS1-v1_5绝对是更安全的选择。 现在将默认值更改为OAEP会破坏使用默认值的每个RSA实现。

otus的建议(在本答案的第一个链接中)更适合于库中的协议实现而不是加密算法。 最后,无论你选择什么,你都应该能够捍卫所做选择的安全性。