私はこの問題で頭がいっぱいです。RSA(4096) を使用して暗号化されたチャネルを実装し、Java (JRE7) を使用して AES 256 ビット キーを配信しようとしています。最初に送信するメッセージは、生成された 256 AES キーを RSA 公開キーで暗号化したものです。復号化すると、次のエラー メッセージが表示されます: javax.crypto.BadPaddingException: Blocktype mismatch: 0
私の復号化コード:
private byte[] decryptMessage(Key key, byte[] data){
Cipher cipher;
System.out.println("Decrypting message...");
System.out.println("key: " + key.toString());
System.out.println("data: " + data);
System.out.println("data length: " + data.length);
if(key instanceof PublicKey){
//RSA public key
System.out.println("Found PublicKey");
try {
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(data);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
// TODO Auto-generated catch block
System.out.println("Failed to decrypt message");
e.printStackTrace();
}
}else if(key instanceof PrivateKey){
//RSA private key
System.out.println("Found PrivateKey");
try {
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] results = cipher.doFinal(data);
System.out.println("Decrypted results: " + results);
return results;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
// TODO Auto-generated catch block
System.out.println("Failed to decrypt message");
e.printStackTrace();
}
}else if(key instanceof SecretKey){
//AES secret key
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(data);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println("Invalid key type");
}
return null;
}
私の暗号化コード:
private byte[] encryptMessage(Key key, byte[] data){
Cipher cipher;
if(key instanceof PrivateKey || key instanceof PublicKey){
//RSA key
try {
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
// TODO Auto-generated catch block
System.out.println("Failed to encrypt message");
e.printStackTrace();
}
}else if(key instanceof SecretKey){
//AES secret key
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
System.out.println("Invalid key type");
}
return null;
}
私はグーグルでいくつかの同様の話に出くわしました(ほとんどはこのWebサイトにあります)が、それらはすべて、異なるデバイス間、たとえばコンピューターからAndroidへのデフォルトのパディングに問題がありました)。同じコンピューターからメッセージを送信するとエラーが発生し、パディングと ECB の両方が設定されています。com.sun.crypto.provider.RSACipher と sun.security.rsa.RSAPadding のソース コードを調べたところ、sun.security.rsa.RSAPadding.unpadV15 メソッドで 2 番目のビットがないためにエラーがスローされていることがわかりました。適切に設定します。また、Java7 の新しい NIO2 クラス、特に AsychronousSocketChannel オブジェクトと CompletionHandler オブジェクトを使用しているため、それらがスレッド エラーを引き起こしているかどうかはわかりませんが、非常に疑わしいです。でソースコードを見つけましたhttp://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/com/sun/crypto/provider/RSACipher.javaおよび http://grepcode.com/file/ repository.grepcode.com/java/root/jdk/openjdk/7-b147/sun/security/rsa/RSAPadding.java#RSAPadding.padV15%28byte[]%29 しかし、やはりあまり役に立ちませんでした。鍵のサイズを落として、暗号オブジェクトのエンコーディング/パディング オプションを変更しようとしましたが、パディングが無効になっていても常にエラーになります。関係ないかもしれませんが、私は JRE7 を使用しているため、bouncycastle の安定したサポートがないため、デフォルトのセキュリティ プロバイダーを使用しています。
前もって感謝します