2015-05-29 549 views
0

我試圖加密和使用JKS密鑰庫file.But而解密我收到以下錯誤......錯誤javax.crypto.IllegalBlockSizeException:解密

這裏是我的加密和解密類解密字符串:

package com.Encrypt; 

import java.io.FileInputStream; 
import java.io.IOException; 
import java.security.InvalidKeyException; 
import java.security.Key; 
import java.security.KeyPair; 
import java.security.KeyStore; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.PrivateKey; 
import java.security.PublicKey; 
import java.security.UnrecoverableEntryException; 
import java.security.UnrecoverableKeyException; 
import java.security.KeyStore.PrivateKeyEntry; 
import java.security.cert.Certificate; 
import java.security.cert.CertificateException; 
import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import org.apache.commons.codec.binary.Base64; 

public class Encrypt { 

public String encyptCard(String card) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnrecoverableKeyException{ 
     FileInputStream is = new FileInputStream("C:/Users/admin/Desktop/keystore/ksjksformat.jks");  
     String keystpassw = "9801461740"; 
     String alias = "ksjksformat";  
      KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());      
      ks.load(is,keystpassw.toCharArray());   
      Certificate cert = ks.getCertificate(alias);    
      PublicKey publicKey = cert.getPublicKey();   
     Cipher cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
     byte[] cipherData = cipher.doFinal(card.getBytes());   
     String cipherData1 = Base64.encodeBase64String(cipherData); 
     return cipherData1;    
    } 
public String decrypte (String encCardNo) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableEntryException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ 
    FileInputStream is = new FileInputStream("C:/Users/admin/Desktop/keystore/ksjksformat.jks");  
    String keystpassw = "9801461740"; 
    String alias = "ksjksformat";  
     KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());      
     ks.load(is,keystpassw.toCharArray());  
     Key key = ks.getKey(alias, keystpassw.toCharArray()); 
     Certificate cert = ks.getCertificate(alias); 
     PublicKey publicKey = cert.getPublicKey(); 
     new KeyPair(publicKey, (PrivateKey) (key));  
     KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(keystpassw.toCharArray()); 
     KeyStore.PrivateKeyEntry pkentry = (PrivateKeyEntry) ks.getEntry(alias, protParam); 
     PrivateKey myPrivateKey =pkentry.getPrivateKey(); 
     Cipher cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.DECRYPT_MODE, myPrivateKey); 
     byte[] cipherData = cipher.doFinal(encCardNo.getBytes()); 
     String decrypted =Base64.decodeBase64(cipherData).toString(); 
     return decrypted; 
} 
} 

這裏是我的課我在哪裏調用這些方法: -

package com.Encrypt; 
import java.io.IOException; 
import java.security.InvalidKeyException; 
import java.security.KeyStoreException; 
import java.security.NoSuchAlgorithmException; 
import java.security.UnrecoverableEntryException; 
import java.security.cert.CertificateException; 
import javax.crypto.BadPaddingException; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
public class CryptoHelper { 
    public static void main(String[] argv) throws InvalidKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, IOException, UnrecoverableEntryException { 

       Encrypt obj = new Encrypt(); 
       String answerEnc = obj.encyptCard("student"); 
       System.out.println("encrypted data----------->"+answerEnc); 
       String Orginial_data = obj.decrypte(answerEnc); 
       System.out.println("Decrypted data-------->"+Orginial_data); 

} 
} 

現在我收到此錯誤: -

Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes 
    at com.sun.crypto.provider.RSACipher.a(DashoA13*..) 
    at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..) 
    at javax.crypto.Cipher.doFinal(DashoA13*..) 
    at com.Encrypt.Encrypt.decrypte(Encrypt.java:56) 
    at com.Encrypt.CryptoHelper.main(CryptoHelper.java:17) 

這個錯誤而解密在public String decrypte (String encCardNo)方法線

byte[] cipherData = cipher.doFinal(encCardNo.getBytes()); 

。請解釋我該如何解決這個問題。

+0

@ Artjom B. ya man這是實際的代碼。通過字符串的學生,我得到這個例外.. :( –

+0

那麼,馬滕的答案是正確的。我正在看加密函數,而不是解密函數。 –

回答

1

您需要解密之前解碼,而不是之後。

至於接受我的答案,同時發佈自己的特殊服務,有點decrypte改寫的:

public String decrypte(final String encCardNo) throws IllegalBlockSizeException, 
     BadPaddingException { 
    // --- setup (should be stored differently) 
    final char[] keystpassw = "9801461740".toCharArray(); 
    final String alias = "ksjksformat"; 

    // --- retrieve private key from store 
    final PrivateKey key; 
    try (final FileInputStream is = new FileInputStream(
      "C:/Users/admin/Desktop/keystore/ksjksformat.jks")) { 
     final KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); 
     ks.load(is, keystpassw); 
     key = (PrivateKey) ks.getKey(alias, keystpassw); 
    } catch (final KeyStoreException | IOException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException e) { 
     throw new IllegalStateException("Could not load key from key store", e); 
    } 

    // --- initialize cipher 
    final Cipher cipher; 
    try { 
     // should use OAEP instead 
     cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, key); 
    } catch (final NoSuchAlgorithmException | NoSuchPaddingException e) { 
     throw new IllegalStateException(
       "RSA PKCS v1.5 should always be available", e); 
    } catch (final InvalidKeyException e) { 
     throw new IllegalStateException("Key is not an RSA private key", e); 
    } 

    // --- decode 
    final byte[] decoded; 
    try { 
     decoded = Base64.getDecoder().decode(encCardNo); 
    } catch (final IllegalArgumentException e) { 
     throw new IllegalArgumentException("Invalid encoded ciphertext", e); 
    } 

    // --- decrypt 
    final byte[] cipherData = cipher.doFinal(decoded); 
    final String cardNo = new String(cipherData, StandardCharsets.US_ASCII); 

    // --- clean up 
    try { 
     key.destroy(); 
    } catch (final DestroyFailedException e) { 
     // we tried, possibly log this 
    } 
    Arrays.fill(cipherData, (byte) 0); 

    return cardNo; 
} 
+0

嗨,如果我解密之前解碼,然後它將如何返回正確data. –

+1

好吧,'card.getBytes()'的反面是'new String(decryptedBytes)',儘管你可能想爲兩者指定一個字符編碼,比如'StandardCharsets.UTF_8'。 –

+0


嗨,
如果我是在解密之前解碼它然後它將如何返回正確的數據
這是我在解密前嘗試解碼時的輸出,然後輸出我得到的是;;;
數據加密和解密 - > **學生**
加密數據withod編碼 - > [B @ c7e553
加密數據與編碼 - > hr ....(Bas e 64編碼數據)
解密數據 - > [B @ 1050169 ..並且不是**學生** –

4

@Maarten Bodewes答案是正確的,我們必須解密之前解碼..
謝謝@Maarten Bodewes
這裏是返回正確輸出的解密方法的代碼。
`

public String decrypte (String encCardNo) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableEntryException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{ 
    FileInputStream is = new FileInputStream("C:/Users/admin/Desktop/keystore/ksjksformat.jks");  
    String keystpassw = "9801461740"; 
    String alias = "ksjksformat";  
     KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());      
     ks.load(is,keystpassw.toCharArray());  
     Key key = ks.getKey(alias, keystpassw.toCharArray()); 
     Certificate cert = ks.getCertificate(alias); 
     PublicKey publicKey = cert.getPublicKey(); 
     new KeyPair(publicKey, (PrivateKey) (key));  
     KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(keystpassw.toCharArray()); 
     KeyStore.PrivateKeyEntry pkentry = (PrivateKeyEntry) ks.getEntry(alias, protParam); 
     PrivateKey myPrivateKey =pkentry.getPrivateKey(); 
     Cipher cipher = Cipher.getInstance("RSA"); 
     cipher.init(Cipher.DECRYPT_MODE, myPrivateKey); 
     byte[] decoded = Base64.decodeBase64(encCardNo);   
     byte[] cipherData = cipher.doFinal(decoded); 
     return new String(cipherData);  
}` 
+1

將此作爲input(未經測試)的例子'decrypte',只是爲了顯示一些編碼提示。 –

相關問題