2015-05-29 522 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',只是为了显示一些编码提示。 –

相关问题