31

AESアルゴリズムを使用してデータを暗号化しようとしていました。ただし、次の例外が発生しました。

java.security.NoSuchAlgorithmException:
    Cannot find any provider supporting AES/ECB/PKCS7PADDING

誰かがこの問題の解決策を知っていますか?私のJDKのバージョンは1.7です。

4

5 に答える 5

47

ブロック暗号の使用にPKCS#7パディングを指定する必要はありません。PKCS#5パディングを指定します。PKCS#5はブロック暗号で使用するように指定されていますが、PKCS#7は指定されていません(S / MIMEなどのさまざまな場所で使用されます)。PKCS#5とPKCS#7は、実際にはまったく同じタイプのパディングを指定していることを指摘します(これらは同じです!)が、このコンテキストで使用される場合は#5と呼ばれます。:)

したがって、の代わりに"AES/ECB/PKCS7PADDING"、が必要です"AES/ECB/PKCS5PADDING"。これは、Javaプラットフォームのすべての実装がサポートする必要がある暗号の実装です。詳細については、クラスのドキュメントをCipher参照してください。

于 2012-04-17T15:21:23.943 に答える
3

AES / ECB / PKCS7Paddingを使用する場合は、弾力がある城がhttp://www.bouncycastle.org/specifications.htmlをサポートします。

于 2013-10-15T09:43:41.003 に答える
3

PKCS#5およびPKCS#7暗号化標準のテキストを含む問題の非常に包括的な説明については、こちらをご覧ください


PKCS#5パディングとは、1〜8バイトのパディングを意味します。パディングバイト自体には、バイトとしてエンコードされたパディングバイトの量が含まれています。DESにはPKCS#5パディングが指定されていますが、ブロックサイズが8バイトのブロック暗号に適しています。

現在、DES仕様、さらにはパスワードベースの暗号化に関するPKCS#5仕様でさえ、かなり長い間Javaに先行しています。AESは、Java、さらにはJava 2が導入されてからずっと後の、2002年にのみ標準化されました。そのため、AESが登場する前に、(トリプル)DESおよびPKCS#5パディングがJavaに統合されました。

Java(より正確にはSun JCEプロバイダー)がAES機能を取得したとき、16バイトのブロックサイズのパディング方法が必要でした。PKCS#7は、PKCS#5パディングと同じこのパディング方法を指定しますが、2〜255バイト(ゼロベースの符号なし整数をエンコードする場合のバイトの最大値)のブロックサイズに対して定義されている点が異なります。ただし、パディング方法はすでに存在していました。名前が付けられまし"PKCS5Padding"た。そのため、新しい名前を導入する代わりに、"PKCS5Padding"単に再利用されました。

"PKCS7Padding"PKCS#5のパディングは単に正しくないため、これまでにSunプロバイダーは実際にサポートする必要があります。これは、Javaの命名の問題だけでなく、暗号化プロトコルを実装したり、他のアプリケーションをJavaに移植したりしようとする開発者にとっての問題です。ただし、今のところ、"PKCS5Padding"の代わりにを使用する必要があり"PKCS7Padding"ます。

于 2015-01-24T22:39:08.220 に答える
0

解決策:ステップ1:bcprov-ext-jdk16-1.46.jar(https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk16/1.46)をプロジェクトに追加します

ステップ2:「Security.addProvider(newBouncyCastleProvider());」という行を追加します。initCiphercommonを退屈させる

次に、プロジェクトを実行します。OK、正常に復号化されます。

于 2020-03-20T02:49:54.807 に答える
0

環境が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

機能した唯一の解決策は、プロバイダーを以下のように弾力がある城として設定することでした。

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);
于 2022-02-24T10:29:03.563 に答える