![](/img/trans.png)
[英]java.security.NoSuchAlgorithmException: Cannot find any provider supporting Blowfish/ECB/PKCS5Padding
[英]java.security.NoSuchAlgorithmException:Cannot find any provider supporting AES/ECB/PKCS7PADDING
我試圖使用 AES 算法加密數據。 但是,發生了以下異常。
java.security.NoSuchAlgorithmException:
Cannot find any provider supporting AES/ECB/PKCS7PADDING
有人知道這個問題的解決方案嗎? 我的 JDK 版本是 1.7。
如果你想使用 AES/ECB/PKCS7Padding 那么充氣城堡將支持 ht tp://www.bouncycastle.org/specifications.html
有關包括 PKCS#5 和 PKCS#7 加密標准文本在內的問題的非常全面的解釋,請查看此處。
PKCS#5 padding 表示填充 1 到 8 個字節。 填充字節本身包含編碼為字節的填充字節量。 為 DES 指定了 PKCS#5 填充,但它適用於塊大小為 8 字節的任何塊密碼。
現在 DES 規范甚至基於密碼的加密的 PKCS#5 規范早於 Java。 AES 直到 2002 年才被標准化,早在 Java 甚至 Java 2 被引入之后。 因此,在 AES 出現之前,(三重)DES 和 PKCS#5 填充已集成到 Java 中。
當 Java——或者更准確地說,Sun JCE 提供者——獲得 AES 功能時,它需要一個 16 字節的塊大小的填充方法。 PKCS#7 指定了與 PKCS#5 padding 相同的填充方法,除了它是為 2 到 255 個字節的塊大小定義的(如果它編碼基於零的無符號整數,則為字節的最大值)。 但是,填充方法已經存在; 它被命名為"PKCS5Padding"
。 因此,沒有引入新名稱, "PKCS5Padding"
簡單地重新使用了"PKCS5Padding"
。
到目前為止,Sun 提供者應該真正支持"PKCS7Padding"
因為 PKCS#5 填充是完全不正確的。 這不僅僅是 Java 命名問題,對於任何試圖實現加密協議或將其他應用程序移植到 Java 的開發人員來說,都是一個問題。 但是現在,您應該使用"PKCS5Padding"
而不是"PKCS7Padding"
。
解決方案: Step1:將 bcprov-ext-jdk16-1.46.jar ( https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk16/1.46 ) 添加到您的項目中
Step2:添加行“Security.addProvider(new BouncyCastleProvider());” 進入 init Cipher common
然后,運行項目,OK,解密成功。
如果環境為Android ,並且您嘗試從文件中讀取 PKCS8 格式的加密私鑰或密碼保護私鑰,請考慮以下解決方案。
我收到的異常如下:
W/System.err: org.bouncycastle.pkcs.PKCSException: unable to read encrypted data: 1.2.840.113549.1.5.13 not available: No provider found for 2.16.840.1.101.3.4.1.42
W/System.err: at org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(Unknown Source:60)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err: at android.os.Looper.loop(Looper.java:223)
W/System.err: at android.os.HandlerThread.run(HandlerThread.java:67)
W/System.err: Caused by: org.bouncycastle.operator.OperatorCreationException: 1.2.840.113549.1.5.13 not available: No provider found for 2.16.840.1.101.3.4.1.42
W/System.err: at org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder$1.get(Unknown Source:322)
W/System.err: at org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(Unknown Source:6)
W/System.err: ... 8 more
W/System.err: Caused by: java.security.NoSuchAlgorithmException: No provider found for 2.16.840.1.101.3.4.1.42
W/System.err: at javax.crypto.Cipher.createCipher(Cipher.java:736)
W/System.err: at javax.crypto.Cipher.getInstance(Cipher.java:619)
W/System.err: at org.bouncycastle.jcajce.util.DefaultJcaJceHelper.createCipher(Unknown Source:0)
W/System.err: at org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder$1.get(Unknown Source:101)
W/System.err: ... 9 more
唯一可行的解決方案是將 Provider 設置為 Bouncy Castle,如下所示:
InputDecryptorProvider decryptorProvider = new JceOpenSSLPKCS8DecryptorProviderBuilder()
.setProvider(new BouncyCastleProvider())
.build(mContext.getResources().getString(R.string.password).toCharArray());
完整的塊代碼如下所示:
privateKeyString = privateKeyString.replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", "").replaceAll(System.lineSeparator(), "")
.replace("-----END ENCRYPTED PRIVATE KEY-----", "");
byte[] keyStringBytes = DatatypeConverter.parseBase64Binary(privateKeyString);
ASN1Sequence asn1Sequence = ASN1Sequence.getInstance(keyStringBytes);
PKCS8EncryptedPrivateKeyInfo pkcs8EncryptedPrivateKeyInfo = new PKCS8EncryptedPrivateKeyInfo(
EncryptedPrivateKeyInfo.getInstance(asn1Sequence));
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
InputDecryptorProvider decryptorProvider = new JceOpenSSLPKCS8DecryptorProviderBuilder()
.setProvider(new BouncyCastleProvider())
.build(mContext.getResources().getString(R.string.password).toCharArray());
PrivateKeyInfo privateKeyInfo = pkcs8EncryptedPrivateKeyInfo.decryptPrivateKeyInfo(decryptorProvider);
mPrivateKey = converter.getPrivateKey(privateKeyInfo);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.