2016-09-15 25 views
0

私は、暗号化/復号化のための非常に基本的なプログラムを書かれており、今ちょうど単一の文字列を暗号化しようとしています。 暗号化が正常に動作しているが、復号化には、エラー基本計画:javax.crypto.BadPaddingException:復号化エラー

javax.crypto.BadPaddingException投げている:復号化エラーを。

は、私が複数の方法を試してみましたが、解決策を見つけることができたスレッドの多くではなく通り抜けた

byte[] decodedData = (rsa.doFinal(decodedValue)); 

下の行にエラーを投げています。誰でもこの問題で私を助けてくれますか?

クラスは、次の暗号化および復号化されたキーストアのロード方法、及び二つの方法の残りの部分であり、第一の試験方法であり、唯一の4つの方法と簡単です。

package XXXX; 

import org.apache.commons.codec.binary.Base64; 

import javax.crypto.*; 
import javax.crypto.spec.SecretKeySpec; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.nio.charset.Charset; 
import java.nio.charset.StandardCharsets; 
import java.security.*; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 


public class EncryptDecryptUtil { 
    private String publicKeyStoreFileName = "C:\\Program Files\\Java\\jdk1.8.0_51\\jre\\lib\\security\\cacerts"; 
    private String pubKeyStorePwd = "XXX"; 
    private String pubKeyAlias="XXXX"; 
    private static final String JKS = "JKS"; 
    private static final int CONST_16 = 16;  

    public String TestMethod(final String clearText) throws InvalidKeyException, NoSuchAlgorithmException, 
      NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, KeyStoreException, 
      CertificateException, IOException, UnrecoverableKeyException {  
     byte[] ecryptedAESKey = generateEncryptedData("TEST"); 
     System.out.println("Encrypted Key = " + ecryptedAESKey); 
     System.out.println("Decrypted Key = " + generateDecryptedData(ecryptedAESKey)); 
     return generateDecryptedData(ecryptedAESKey); 
    } 

    private KeyStore loadKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, 
      IOException { 
     KeyStore keystore = KeyStore.getInstance(JKS); 
     FileInputStream tmp = new FileInputStream(publicKeyStoreFileName); 
     keystore.load(tmp, pubKeyStorePwd.toCharArray()); 
     tmp.close(); 
     return keystore; 
    } 

    private byte[] generateEncryptedData(final String data) throws NoSuchAlgorithmException, 
      NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, 
      KeyStoreException, CertificateException, IOException, UnrecoverableKeyException { 
      Base64 base64 = new Base64(); 
      X509Certificate cert; 
      KeyStore keystore = loadKeyStore(); 
      cert = (java.security.cert.X509Certificate) keystore.getCertificate(pubKeyAlias); 
      Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
      rsa.init(Cipher.ENCRYPT_MODE, cert); 

      byte[] ecrypteddata = (base64.encode(rsa.doFinal(data.getBytes(StandardCharsets.UTF_8)))); 
      return ecrypteddata; 
    } 

    public String generateDecryptedData(final byte[] encryptedData) throws NoSuchAlgorithmException, 
      NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, 
      KeyStoreException, CertificateException, IOException, UnrecoverableKeyException { 
      Base64 base64 = new Base64(); 
      X509Certificate cert; 
      KeyStore keystore = loadKeyStore(); 
      cert = (java.security.cert.X509Certificate) keystore.getCertificate(pubKeyAlias); 
      Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
      rsa.init(Cipher.DECRYPT_MODE, cert); 
      byte[] decodedValue = base64.decode(encryptedData); 
      byte[] decodedData = (rsa.doFinal(decodedValue)); 
      return new String(decodedData); 
    }  
} 
+0

、あなたのシステムエンコーディングとしてUTF-8を使用していますか?おそらく... ... byte [] ecryptedAESKey = generateEncryptedData(new String( "TEST"、 "UTF-8"));を実行してみてください。 –

+0

ありがとうございました。私はすでにUTF-8(単にdata.getBytes())とUTF-8なしで試してみました。また、encryptterからdecrypterへのデータをバイト配列として渡すことも試みましたが、文字列としてhexdataと同じように成功しませんでしたが、同じエラー – user3452558

答えて

0

Java APIは、証明書と(RSA)秘密鍵の違いになります。秘密鍵は、証明書に関連付けられていますが、ではなく、の証明書の一部です。 Java(幸いにも)は、この点でMicrosoftの.NET APIと異なり、.NET APIはそのような悪い設計の選択肢でいっぱいです。あなたがしようとしているとき

rsa.init(Cipher.DECRYPT_MODE, cert); 

を、あなたはエラーを期待するべきです。しかしこの問題は、RSAベースの署名を公開鍵で未処理の「復号化」するために使用されることがあります。したがって、常に秘密鍵で解読する必要がありますが、公開鍵で解読することは明示的に許可されていません(Sunプロバイダの場合)。

代わりに、KeyStore#getKeyまたは(より現代的だが複雑な)KeyStore#getEntryを使用して秘密鍵を取得してみてください。つまり、の場合は本当にキーストアに秘密鍵を持ち、それを取得するためのパスワードを持っています。

以下
+0

お返事ありがとうございます。私はすでにそれを試みました。 〜rsa.init(Cipher.DECRYPT_MODE、keystore.getKey(pubKeyAlias、pubKeyStorePwd.toCharArray())); 〜 上記のコードでも同じエラーが発生します。また、base64.decodeとbase64.encodeを使わずに、暗号化されたデータを直接渡すだけで、同じエラーが返されます:( – user3452558

+0

秘密鍵を返しますか?返された鍵を 'PrivateKey'にキャストしてみてください。 –

+0

はい、返信します** [email protected]**。 実際の値を取得できませんでした。値を出力するにはlibにメソッドがないためです。 – user3452558

-1

が最終作業コードです:

import org.apache.commons.codec.binary.Base64; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.nio.charset.StandardCharsets; 
import java.security.*; 
import java.security.cert.CertificateException; 
import java.security.cert.X509Certificate; 

/** 
* Created by Suchit Pandya on 9/16/2016. 
*/ 
public class EncryptLogic2 { 

    private String publicKeyStoreFileName = "C:\\Program Files\\Java\\jdk1.8.0_51\\jre\\lib\\security\\cacerts"; 
    private String pubKeyStorePwd = "password"; 
    private String pubKeyAlias="certName"; 
    private static final String JKS = "JKS"; 
    private static final String SHA1PRNG = "SHA1PRNG"; 
    private static final String RSA = "RSA/ECB/PKCS1Padding"; 
    private static final int CONST_16 = 16; 
    private static byte[] asKey; 


    public String TestMethod(final String clearText) throws InvalidKeyException, NoSuchAlgorithmException, 
      NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, KeyStoreException, 
      CertificateException, IOException, UnrecoverableKeyException { 

     String ecryptedData = generateEncryptedData(clearText); 
     String decryptedData = generateDecryptedData(ecryptedData); 
     System.out.println("*********** Decrypted Data = " + decryptedData); 
     return decryptedData; 
    } 

    private KeyStore loadKeyStore() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, 
      IOException { 
     KeyStore keystore = KeyStore.getInstance(JKS); 
     FileInputStream tmp = new FileInputStream(publicKeyStoreFileName); 
     keystore.load(tmp, pubKeyStorePwd.toCharArray()); 
     tmp.close(); 
     return keystore; 
    } 

    private String generateEncryptedData(final String data) throws NoSuchAlgorithmException, 
      NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, 
      KeyStoreException, CertificateException, IOException, UnrecoverableKeyException { 
     Base64 base64 = new Base64(); 
     X509Certificate cert; 
     KeyStore keystore = loadKeyStore(); 
     cert = (java.security.cert.X509Certificate) keystore.getCertificate(pubKeyAlias); 
     Cipher rsa = Cipher.getInstance(RSA); 
     Key key = cert.getPublicKey(); 
     rsa.init(Cipher.ENCRYPT_MODE, key); 

     byte[] ecrypteddata = rsa.doFinal(data.getBytes(StandardCharsets.UTF_8)); 
     return Base64.encodeBase64String(ecrypteddata); 
    } 

    public String generateDecryptedData(final String encryptedData) throws NoSuchAlgorithmException, 
      NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, 
      KeyStoreException, CertificateException, IOException, UnrecoverableKeyException { 
     Base64 base64 = new Base64(); 
     X509Certificate cert; 
     KeyStore keystore = loadKeyStore(); 
     Cipher rsa = Cipher.getInstance(RSA); 
     Key key = keystore.getKey(pubKeyAlias, pubKeyStorePwd.toCharArray()); 
     rsa.init(Cipher.DECRYPT_MODE, key); 
     byte[] decodedValue = base64.decode(encryptedData); 
     byte[] decodedData = (rsa.doFinal(decodedValue)); 
     return new String(decodedData, StandardCharsets.UTF_8); 
    } 
} 
+0

RSA暗号化をセッションキーやファンシーグループ算術のために慎重に作成したデータに使用すると、警告が出る可能性が非常に高いです。その周りの数学は理解することは難しいですが、物事は遅いですが、サイズは制限されていません。あなたは、経験を積んだようなハイブリッドモードを使うのがよいでしょう。 – eckes

+0

@eckes:私はすでに研究を行っていますが、それでもRSAは私の要求に合っています。私は丁寧に細工されたデータにのみ使用しています。私のデータは、同じサーバー上でのみ暗号化および復号化され、エラーシナリオの場合には一時的にディスクに保存されます。 16バイトを超えることはありません。私はここですべてのリスクを理解しています。私はちょうどこのソリューションを投稿したので、RSAコードを探している人がいれば、それを見つけることができます。その答えを否定的なものとしてマークしないでください。 – user3452558

+0

@eckes:会話に従うならば、この投稿の全ポイントはRSAの実用的な解決策を得ることでした。これはRSAソリューションにとって有効な答えです。 – user3452558