如何解决javax.crypto.IllegalBlockSizeException:数据不能超过256个字节

时间:2015-04-09 06:54:34

标签: java encryption aes rsa

enter image description here我有一个16字节长的AES密钥。我想加密16字节密钥3次。在第一次迭代时,密钥大小更改为16到256个字节。下一次迭代时密钥大小更改为256到689个字节。下一次迭代引发了sreenshot中显示的异常。 这是因为我的RSA算法不支持密钥长度大于256字节 .RSA加密源代码如下所示

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.sql.SQLException;

import javax.crypto.Cipher;

    public class RSAKeyPack implements Serializable {

      private static final long serialVersionUID = 2L;
      PublicKey publicKey;
      PrivateKey privateKey;
        //KeyPairGenerator keyPairGenerator;
        transient KeyPairGenerator keyPairGenerator;

        private  void getGenerator() throws NoSuchAlgorithmException {
           if (keyPairGenerator == null) {
               keyPairGenerator = KeyPairGenerator.getInstance("RSA");
               keyPairGenerator.initialize(1024); //1024 used for normal securities
               KeyPair keyPair = keyPairGenerator.generateKeyPair();  
               publicKey = keyPair.getPublic();  
               privateKey = keyPair.getPrivate();
           }

        }
        public RSAKeyPack()
        {

            try {
                getGenerator();
            } catch (NoSuchAlgorithmException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            /*try 
            {

                keyPairGenerator = KeyPairGenerator.getInstance("RSA");
                keyPairGenerator.initialize(2048); //1024 used for normal securities
                KeyPair keyPair = keyPairGenerator.generateKeyPair();  
                 publicKey = keyPair.getPublic();  
                privateKey = keyPair.getPrivate();          
            } 
            catch (NoSuchAlgorithmException e) 
            {
                e.printStackTrace();
            }*/
        }

        public PublicKey getPublicKey() {
            return publicKey;
        }

        public void setPublicKey(PublicKey publicKey) {
            this.publicKey = publicKey;
        }

        public PrivateKey getPrivateKey() {
            return privateKey;
        }

        public void setPrivateKey(PrivateKey privateKey) {
            this.privateKey = privateKey;
        }



        public   BigInteger  getParamModulus(PublicKey publickey) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
        {

                 KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
                 RSAPublicKeySpec rsaPubKeySpec = keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);  
                 //RSAPrivateKeySpec rsaPrivKeySpec = keyFactory.getKeySpec(privateKey, RSAPrivateKeySpec.class);  
                 System.out.println("PubKey Modulus : " + rsaPubKeySpec.getModulus());


            return rsaPubKeySpec.getModulus();
           }  

        public   BigInteger  getParamExponent(PublicKey publickey) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
        {

                 KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
                 RSAPublicKeySpec rsaPubKeySpec = keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);  
                 //RSAPrivateKeySpec rsaPrivKeySpec = keyFactory.getKeySpec(privateKey, RSAPrivateKeySpec.class);  
                 System.out.println("PubKey Modulus : " + rsaPubKeySpec.getPublicExponent());


            return rsaPubKeySpec.getPublicExponent();
           }  


         public static PublicKey readPublicKey(BigInteger modulus,BigInteger exponent) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException{  


                  //Get Public Key  
                  RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(modulus, exponent);  
                  KeyFactory fact = KeyFactory.getInstance("RSA");  
                  PublicKey publicKey = fact.generatePublic(rsaPublicKeySpec);  
                  return publicKey;  


         }   


         public  byte[] encryptData(byte[] data,PublicKey pubKey) throws IOException {  


                 byte[] encryptedData = null;  
                 try {  

                        Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");  
                        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

                        System.out.println("data key length after encryption"+data.length);
                        encryptedData = cipher.doFinal(data);  
                        System.out.println("data key length after encryption"+encryptedData.length);

                 } catch (Exception e) {  
                     System.out.println("----------------ENCRYPTION ABANDONED!!!------------"); 
                        e.printStackTrace();  
                 }   


                 return (encryptedData);  
             }  


         public    byte[] decryptData(byte[] data,PrivateKey privateKey) throws IOException {  

              byte[] descryptedData = null;  

              try {  

               Cipher cipher = Cipher.getInstance("RSA/ECB/NoPadding");

               cipher.init(Cipher.DECRYPT_MODE, privateKey);  
               descryptedData = cipher.doFinal(data);  
               System.out.println("data key length after decryption     "+data.length);

              } catch (Exception e) {  
               e.printStackTrace();  
              }   

              return descryptedData ;

             }  
    }

2 个答案:

答案 0 :(得分:2)

您可以使用对称密钥来加密和解密要传输的数据(> 256)。 RSA只能在一定程度上加密数据(例如256字节),这取决于RSA密钥长度。

这意味着如果要传输大于256字节的任何内容,则必须传输对称密钥<首先是256个字节,因此您可以拥有以下内容:

  
      
  1. 生成对称密钥(< 256字节)
  2.   
  3. 使用RSA加密对称密钥
  4.   
  5. 传输加密对称密钥
  6.   
  7. 使用RSA解密对称密钥
  8.   
  9. 使用对称密钥加密数据(> 256字节)
  10.   
  11. 传输加密数据
  12.   
  13. 使用对称密钥解密加密数据
  14.   

或(同时传输加密的对称密钥和加密数据)

  
      
  1. 生成对称密钥(< 256字节)
  2.   
  3. 使用RSA加密对称密钥
  4.   
  5. 使用对称密钥加密数据(> 256字节)
  6.   
  7. 传输加密对称密钥&加密数据
  8.   
  9. 使用RSA解密对称密钥
  10.   
  11. 使用对称密钥解密加密数据
  12.   

答案 1 :(得分:-2)

您需要通过publicKey分割数据

int keyLength = publicKey.getModulus().bitLength() / 16;
String[] datas = splitString(data, keyLength - 11);
String mi = ""//the data after encrypted;
for (String s : datas) {
     mi += bcd2Str(cipher.doFinal(s.getBytes()));
}
return mi;


public static String bcd2Str(byte[] bytes) {
    char temp[] = new char[bytes.length * 2], val;

    for (int i = 0; i < bytes.length; i++) {
        val = (char) (((bytes[i] & 0xf0) >> 4) & 0x0f);
        temp[i * 2] = (char) (val > 9 ? val + 'A' - 10 : val + '0');

        val = (char) (bytes[i] & 0x0f);
        temp[i * 2 + 1] = (char) (val > 9 ? val + 'A' - 10 : val + '0');
    }
    return new String(temp);
}