最近生活亂七八糟,什麼都懶上了天。感覺自己會的東西好少
上司新配置設定了一個任務,讓我将http換成https,對參數進行加密
可選擇有兩個加密算法AES和RSA
由于公司内部使用,且資料量大,可以用私鑰。于是就用AES。
AES
1.概念
AES又叫Rijndael算法,是DES更新的加密标準,運作要求低,不需計算機有非常高的處理能力和大的記憶體;
操作可以很容易的抵禦時間和空間的攻擊,在不同的運作環境下始終保持良好的性能;
AES密鑰長度:最長隻有256bit,可用軟體和硬體實作高速處理;
密鑰管理:要求在通信前對密鑰進行秘密配置設定,解密的私鑰必須通過網絡傳送至加密資料接收方;
AES加密速度很快;
對稱加密;
2.幫助類
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import com.util.encrypt.Base64;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class AesEncrypt {
private static final String AES_STR = "AES";
private static final String SHA1PRNG_STR = "SHA1PRNG";
public static String encrypt(String bef_aes, String password) {
byte[] byteContent = null;
try {
byteContent = bef_aes.getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encrypt(byteContent,password);
}
public static String encrypt(byte[] content, String password) {
try {
SecretKey secretKey = getKey(password);
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, AES_STR);
Cipher cipher = Cipher.getInstance(AES_STR);// 建立密碼器
cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
String aft_aes = parseByte2HexStr(result);
return aft_aes; // 加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
public static String decrypt(String aft_aes_base64, String password,String charset){
String aft_aes="";
try {
aft_aes = Base64.decode(aft_aes_base64);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return decrypt(aft_aes,password);
}
public static String decrypt(String aft_aes, String password) {
try {
byte[] content = parseHexStr2Byte(aft_aes);
SecretKey secretKey = getKey(password);
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, AES_STR);
Cipher cipher = Cipher.getInstance(AES_STR);// 建立密碼器
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
byte[] result = cipher.doFinal(content);
String bef_aes = new String(result);
return bef_aes; // 加密
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length()/2];
for (int i = 0;i< hexStr.length()/2; i++) {
int value = Integer.parseInt(hexStr.substring(i*2, i*2+2), 16);
result[i] = (byte)value;
}
return result;
}
public static SecretKey getKey(String strKey) {
try {
KeyGenerator _generator = KeyGenerator.getInstance(AES_STR);
SecureRandom secureRandom = SecureRandom.getInstance(SHA1PRNG_STR);
secureRandom.setSeed(strKey.getBytes());
_generator.init(128,secureRandom);
return _generator.generateKey();
} catch (Exception e) {
throw new RuntimeException("初始化密鑰出現異常");
}
}
/**
* AES的加密函數
* @param str 傳入需要加密的字元
* @param key 傳入一個16位長度的密鑰。否則報錯
* @return 執行成功傳回加密結果,否則報錯
* @throws Exception 抛出一個加密異常
*/
@SuppressWarnings("restriction")
public static String aesEncrypt(String str, String key) throws Exception {
if (str == null || key == null) return null;
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
byte[] bytes = cipher.doFinal(str.getBytes("utf-8"));
return new BASE64Encoder().encode(bytes);
}
/**
* AES的解密函數
* @param str 傳入需要解密的字元
* @param key 傳入一個16位長度的密鑰。否則報錯
* @return 執行成功傳回加密結果,否則報錯
* @throws Exception 抛出一個解密異常
*/
@SuppressWarnings("restriction")
public static String aesDecrypt(String str, String key) throws Exception {
if (str == null || key == null) return null;
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
byte[] bytes = new BASE64Decoder().decodeBuffer(str);
bytes = cipher.doFinal(bytes);
return new String(bytes, "utf-8");
}
}
3.controller
//如果參數的加密後的位元組流,則需要先解密然後轉Object
@RequestMapping(value="/ts",method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody String aa(@RequestBody String param)
{
byte[] byteContent = param.getBytes("utf-8");
String key="ABCDEFGHIJKLMNRS";//秘鑰
String dataJson="";//加密内容
//去除Base64 和hex:用字元串形式看二進制代碼 将二進制轉化成16進制
String simpleResult = AesEncrypt.aesEncrypt(dataJson, key);//加密後的密文
String simpleContent= AesEncrypt.aesDecrypt(dataJson, key);//解密後的内容
String result = AesEncrypt.encrypt(dataJson, key);//加密後的密文
String content= AesEncrypt.decrypt(dataJson, key);//解密後的内容
}
RSA
1.概念
是公開密鑰系統的代表;
安全性:建立在具有大素數因子的合數,其因子分解困難這一法則之上;
處理速度慢;
密鑰管理:加解密過程中不必網絡傳輸保密的密鑰;密鑰管理優于AES算法;
RSA加解密速度慢,不适合大量資料檔案加密;
公鑰加密 私鑰解密
鑰加密 公鑰解密 使用簽名确定是否為該私鑰加密
2.使用
//非對稱密鑰算法
public static final String KEY_ALGORITHM = "RSA";
/**
* 密鑰長度,DH算法的預設密鑰長度是1024
* 密鑰長度必須是64的倍數,在512到65536位之間
*/
private static final int KEY_SIZE = 512;
//公鑰
private static final String PUBLIC_KEY = "RSAPublicKey";
//私鑰
private static final String PRIVATE_KEY = "RSAPrivateKey";
/**
* 初始化密鑰對
*
* @return Map 甲方密鑰的Map
*/
public static Map<String, Object> initKey() throws Exception {
//執行個體化密鑰生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
//初始化密鑰生成器
keyPairGenerator.initialize(KEY_SIZE);
//生成密鑰對
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//甲方公鑰
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
//甲方私鑰
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
//将密鑰存儲在map中
Map<String, Object> keyMap = new HashMap<String, Object>();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
* 私鑰加密
*
* @param data 待加密資料
* @param key 密鑰
* @return byte[] 加密資料
*/
public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
//取得私鑰
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//生成私鑰
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
//資料加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公鑰加密
*
* @param data 待加密資料
* @param key 密鑰
* @return byte[] 加密資料
*/
public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
//執行個體化密鑰工廠
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//初始化公鑰
//密鑰材料轉換
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
//産生公鑰
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
//資料加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return cipher.doFinal(data);
}
/**
* 私鑰解密
*
* @param data 待解密資料
* @param key 密鑰
* @return byte[] 解密資料
*/
public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
//取得私鑰
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//生成私鑰
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
//資料解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 公鑰解密
*
* @param data 待解密資料
* @param key 密鑰
* @return byte[] 解密資料
*/
public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {
//執行個體化密鑰工廠
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//初始化公鑰
//密鑰材料轉換
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
//産生公鑰
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
//資料解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, pubKey);
return cipher.doFinal(data);
}
/**
* 取得私鑰
*
* @param keyMap 密鑰map
* @return byte[] 私鑰
*/
public static byte[] getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
/**
* 取得公鑰
*
* @param keyMap 密鑰map
* @return byte[] 公鑰
*/
public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
使用
//初始化密鑰
//生成密鑰對
Map<String, Object> keyMap = initKey();
//公鑰
byte[] publicKey = getPublicKey(keyMap);
//私鑰
byte[] privateKey = getPrivateKey(keyMap);
System.out.println("公鑰:/n" + Base64.encodeBase64String(publicKey));
System.out.println("私鑰:/n" + Base64.encodeBase64String(privateKey));
System.out.println("================密鑰對構造完畢,甲方将公鑰公布給乙方,開始進行加密資料的傳輸=============");
String str = "RSA密碼交換算法";
System.out.println("/n===========甲方向乙方發送加密資料==============");
System.out.println("原文:" + str);
//甲方進行資料的加密
byte[] code1 = encryptByPrivateKey(str.getBytes(), privateKey);
System.out.println("加密後的資料:" + Base64.encodeBase64String(code1));
System.out.println("===========乙方使用甲方提供的公鑰對資料進行解密==============");
//乙方進行資料的解密
byte[] decode1 = decryptByPublicKey(code1, publicKey);
System.out.println("乙方解密後的資料:" + new String(decode1) + "/n/n");
System.out.println("===========反向進行操作,乙方向甲方發送資料==============/n/n");
str = "乙方向甲方發送資料RSA算法";
System.out.println("原文:" + str);
//乙方使用公鑰對資料進行加密
byte[] code2 =encryptByPublicKey(str.getBytes(), publicKey);
System.out.println("===========乙方使用公鑰對資料進行加密==============");
System.out.println("加密後的資料:" + Base64.encodeBase64String(code2));
System.out.println("=============乙方将資料傳送給甲方======================");
System.out.println("===========甲方使用私鑰對資料進行解密==============");
//甲方使用私鑰對資料進行解密
byte[] decode2 = decryptByPrivateKey(code2, privateKey);
System.out.println("甲方解密後的資料:" + new String(decode2));