如果用RSA加密數(shù)據(jù)的話,會有數(shù)據(jù)長度的要求,否則會拋異常:
javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes
推薦的做法:
- 隨機(jī)生成一個密鑰,用作對稱密鑰UUID
- 用此對稱密鑰,用對稱加密法AES加密數(shù)據(jù)
- 用RSA的公鑰加密此對稱密鑰
- 發(fā)送加密后的對稱密鑰和加密數(shù)據(jù)
- 用RSA私鑰解密加密后的對稱密鑰
- 用解密密后的對稱密鑰,解密數(shù)據(jù)
- 完成
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;
/**
* 用來進(jìn)行加密的操作
*
* @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;
}
/**
* 用來進(jìn)行解密的操作
*
* @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);
}
/**
* 根據(jù)密鑰和算法生成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 = "恭喜發(fā)財!";// 要加密的字符串
System.out.println("準(zhǔn)備用密鑰加密的字符串為:" + source);
String cryptograph = encrypt(keyString, source);// 生成的密文
System.out.print("用密鑰加密后的結(jié)果為:" + 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、產(chǎn)生AES密鑰
String keyString = AESSecurityUtil.generateKeyString();
//2、用AES法加密數(shù)據(jù)
String cryptograph = AESSecurityUtil.encrypt(keyString, data);
//3、用RSA加密AES密鑰
String finalKey = RSASecurityUtil.encrypt(keyString);
// System.out.print("用RSA加密AES密鑰為:" + finalKey);
// System.out.print("加密數(shù)據(jù):" + cryptograph);
CryptoData cryptoData = new CryptoData();
cryptoData.setKey(finalKey);
cryptoData.setContent(cryptograph);
//4、返回數(shù)據(jù)
return cryptoData;
}
public static String decrypt(String keyString, String data) throws Exception
{
//1、解密密鑰
String decryptKeyString = RSASecurityUtil.decrypt(keyString);
//2、解密內(nèi)容
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 + "]";
}
}