javax.crypto.Cipher能否为不同的提供者返回不同的结果?

javax.crypto.Cipher能否为不同的提供者返回不同的结果?,java,encryption,Java,Encryption,检索javax.crypto.Cipher的实例时,您可以请求特定的提供者或让系统选择一个: Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding" /*, here may be Provider parameter*/); 是否保证省略provider参数将始终有效,并且在一个系统上加密的消息可以在另一个系统上解密? 或者,换句话说,提供程序是否只负责实现,并且由提供程序A加密的文本始终可以由提供程序B解密?中的Oracle是这样

检索
javax.crypto.Cipher
的实例时,您可以请求特定的提供者或让系统选择一个:

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding" /*, here may be Provider parameter*/);
是否保证省略provider参数将始终有效,并且在一个系统上加密的消息可以在另一个系统上解密?
或者,换句话说,提供程序是否只负责实现,并且由提供程序A加密的文本始终可以由提供程序B解密?

中的Oracle是这样说的:

实现互操作性意味着各种实现可以 相互合作,使用对方的钥匙,或验证对方的身份 签名。这意味着,例如,对于相同的 算法,由一个提供者生成的密钥可由 一个提供者生成的签名是可验证的 被另一个

因此,不同提供者的结果应该匹配
仍然是@Artjom B.提到的bug可能会发生。

您正在使用,因此代码将始终有效。如果另一个优先级高于标准提供程序的提供程序实现了相同的算法,则选择此提供程序。但是提供者在这里并不重要

只有当参数IV(初始化向量)相同时,使用PKCS#5填充的AES加密才会产生相同的结果

您可以将IV传递给init方法,也可以让提供程序为您生成随机IV:

cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));

cipher.init(Cipher.ENCRYPT_MODE, secretKey); // random IV
您可以通过调用getIV()查询随机IV:


如果您了解IV,您可以使用实现AES/CBC/PKCS5P的每个JCE提供程序解密结果,甚至可以使用另一种编程语言(例如使用openssl的C)。这就是加密标准的要点。

我认为操作模式/填充的默认值没有标准化,但忽略它们是个坏主意。每个完全限定的密码名称都应该产生相同的输出,因为所有内容都是标准化的。但是错误发生了,你不能确定。如果它不是完全限定的(例如,
“AES”
),那么提供者将使用CodesInChaos所说的自己的默认值。我不知道这个问题是否能正确回答。对不起,我的问题不是关于模式和填充。仅关于提供者。有趣的是,需要将iv+加密数据传递给解密程序。只有当加密和解密程序都知道init向量[IV]的长度和密钥时,该机制才会成功。只是添加一些指针以获得更好的图片。
byte[] iv = cipher.getIV();