javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes 解决办法

javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes 解决办法

如果用RSA加密数据的话,会有数据长度的要求,否则会抛异常:
javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes

推荐的做法:

  1. 随机生成一个密钥,用作对称密钥UUID
  2. 用此对称密钥,用对称加密法AES加密数据
  3. 用RSA的公钥加密此对称密钥
  4. 发送加密后的对称密钥和加密数据
  5. 用RSA私钥解密加密后的对称密钥
  6. 用解密密后的对称密钥,解密数据
  7. 完成
AESSecurityUtil.java
import java.security.Key;
import java.util.UUID;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public  class AESSecurityUtil {

     //  加密算法
     /**  指定加密算法为RSA  */
     private  static  final String ALGORITHM = "AES";

     //  加密密钥
    
//  private static final byte[] keyValue = new byte[] { 'T', 'h', 'e',
    
//  'B','e', 's', 't', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };
    
//  16位的加密密钥
//     private byte[] keyValue;

     /**
     * 用来进行加密的操作
     * 
     * 
@param  Data
     * 
@return
     * 
@throws  Exception
     
*/
     public  static String encrypt(String keyString, String data)
             throws Exception {
        Key key = generateKey(keyString);
        Cipher c = Cipher.getInstance(ALGORITHM);
        c.init(Cipher.ENCRYPT_MODE, key);
         byte[] encVal = c.doFinal(data.getBytes());
        String encryptedValue =  new BASE64Encoder().encode(encVal);
         return encryptedValue;
    }

     /**
     * 用来进行解密的操作
     * 
     * 
@param  encryptedData
     * 
@return
     * 
@throws  Exception
     
*/
     public  static String decrypt(String keyString, String encryptedData)  throws Exception {
        Key key = generateKey(keyString);
        Cipher c = Cipher.getInstance(ALGORITHM);
        c.init(Cipher.DECRYPT_MODE, key);
         byte[] decordedValue =  new BASE64Decoder().decodeBuffer(encryptedData);
         byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue =  new String(decValue);
         return decryptedValue;
    }
    
     public  static String generateKeyString()
    {
         // 必须长度为16
         return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
    }

     /**
     * 根据密钥和算法生成Key
     * 
     * 
@return
     * 
@throws  Exception
     
*/
     private  static Key generateKey(String keyString)  throws Exception {
        Key key =  new SecretKeySpec(keyString.getBytes(), ALGORITHM);
         return key;
    }
    
     public  static  void main(String [] args)  throws Exception
    {
        String keyString = generateKeyString();
//         String keyString = "1234567890123456";
        System.out.println("密钥:" + keyString);
        
        String source = "恭喜发财!"; //  要加密的字符串
        System.out.println("准备用密钥加密的字符串为:" + source);
        
        String cryptograph = encrypt(keyString, source); //  生成的密文
        System.out.print("用密钥加密后的结果为:" + cryptograph);
        System.out.println();

        String target = decrypt(keyString, cryptograph); //  解密密文
        System.out.println("用密钥解密后的字符串为:" + target);
        System.out.println();
    }

}


CryptoUtil.java
import com.tcl.project7.boss.common.crypto.CryptoData;
import com.tcl.project7.boss.common.util.JsonManager;
import com.tcl.project7.boss.common.util.file.FileUtil;
import com.tcl.project7.boss.gameapplication.yearendactivities.bigwheelgame.player.valueobject.BigWheelGameRequest;

public  class CryptoUtil {
    
     public  static CryptoData encrypt(String data)  throws Exception
    {
         // 1、产生AES密钥
        String keyString = AESSecurityUtil.generateKeyString();
        
         // 2、用AES法加密数据
        String cryptograph = AESSecurityUtil.encrypt(keyString, data);
        
         // 3、用RSA加密AES密钥
        String finalKey = RSASecurityUtil.encrypt(keyString);
//         System.out.print("用RSA加密AES密钥为:" + finalKey);
//         System.out.print("加密数据:" + cryptograph);
        
        CryptoData cryptoData =  new CryptoData();
        cryptoData.setKey(finalKey);
        cryptoData.setContent(cryptograph);
        
         // 4、返回数据
         return cryptoData;
    }
    
     public  static String decrypt(String keyString, String data)  throws Exception
    {
         // 1、解密密钥
        String decryptKeyString = RSASecurityUtil.decrypt(keyString);
        
         // 2、解密内容
        String decryptData = AESSecurityUtil.decrypt(decryptKeyString, data);
        
         // 3、返回
         return decryptData;
        
    }
    
     public  static  void main(String [] args)  throws Exception
    {
        String aFilePath = "DATA/TESTING-FILE/TOCRYPTO/tocrypto.txt";
        String source = FileUtil.getContents(aFilePath);
        
        CryptoData cryptoData = encrypt(source);
        System.out.print(cryptoData);
        
        String target = decrypt(cryptoData.getKey(), cryptoData.getContent());
        System.out.print(target);
        
        BigWheelGameRequest bigWheelGameRequest = JsonManager.getBean(target, BigWheelGameRequest. class);
        System.out.print(bigWheelGameRequest);
    }

}


CryptoData.java
import java.io.Serializable;

public  class CryptoData  implements Serializable{

     private  static  final  long serialVersionUID = -4774469372648172844L;
    
     private String key;
    
     private String content;

     public String getKey() {
         return key;
    }

     public  void setKey(String key) {
         this.key = key;
    }

     public String getContent() {
         return content;
    }

     public  void setContent(String content) {
         this.content = content;
    }

     public String toString() {
         return "CryptoData [key=" + key + ", content=" + content + "]";
    }

}

你可能感兴趣的:(javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes 解决办法)