AES/CBC/PKCS7加密 以及PKCS5加密簡單實用
阿新 • • 發佈:2018-11-19
高階加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高階加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日釋出於FIPS PUB 197,並在2002年5月26日成為有效的標準。2006年,高階加密標準已然成為對稱金鑰加密中最流行的演算法之一。
高階加密標準(AES,Advanced Encryption Standard)為最常見的對稱加密演算法(微信小程式加密傳輸就是用這個加密演算法的)。對稱加密演算法也就是加密和解密用相同的金鑰
在這裡簡單介紹下對稱加密演算法與非對稱加密演算法的區別。
對稱加密演算法
加密和解密用到的金鑰是相同的,這種加密方式加密速度非常快,適合經常傳送資料的場合。缺點是金鑰的傳輸比較麻煩。
非對稱加密演算法
加密和解密用的金鑰是不同的,這種加密方式是用數學上的難解問題構造的,通常加密解密的速度比較慢,適合偶爾傳送資料的場合。優點是金鑰傳輸方便。常見的非對稱加密演算法為RSA、ECC和EIGamal。
實際中,一般是通過RSA加密AES的金鑰,傳輸到接收方,接收方解密得到AES金鑰,然後傳送方和接收方用AES金鑰來通訊。
PKCS7 的工具類,加密之前用十六進位制編過碼
package com.example.administrator.standardOA.utils; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.crypto.spec.IvParameterSpec; import java.io.UnsupportedEncodingException; /** * Created by Duqianlong on 2018/11/15. */ public class AESPKCS7PaddingUtils { /** * 演算法/模式/填充 **/ private static final String CipherMode = "AES/CBC/PKCS7Padding"; // 建立金鑰, 長度為128位(16bytes), 且轉成位元組格式 private static SecretKeySpec createKey(String key) { byte[] data = null; if (key == null) { key = ""; } StringBuffer sb = new StringBuffer(16); sb.append(key); while (sb.length() < 16) { sb.append("0"); } if (sb.length() > 16) { sb.setLength(16); } try { data = sb.toString().getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return new SecretKeySpec(data, "AES"); } // 建立初始化向量, 長度為16bytes, 向量的作用其實就是salt private static IvParameterSpec createIV(String iv) { byte[] data = null; if (iv == null) { iv = ""; } StringBuffer sb = new StringBuffer(16); sb.append(iv); while (sb.length() < 16) { sb.append("0"); } if (sb.length() > 16) { sb.setLength(16); } try { data = sb.toString().getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return new IvParameterSpec(data); } /****************************************************************************/ // 加密位元組資料, 被加密的資料需要提前轉化成位元組格式 private static byte[] encrypt(byte[] content, String key, String iv) { try { SecretKeySpec secretKeySpec = createKey(key); IvParameterSpec ivParameterSpec = createIV(iv); Cipher cipher = Cipher.getInstance(CipherMode); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] result = cipher.doFinal(content); // 加密 return result; } catch (Exception e) { e.printStackTrace(); } return null; } // 加密字串資料, 返回的位元組資料還需轉化成16進位制字串 public static String encrypt(String content, String key) { byte[] data = null; try { data = content.getBytes("UTF-8"); } catch (Exception e) { e.printStackTrace(); } data = encrypt(data, key, "text1234"); return byte2hex(data); } /****************************************************************************/ // 解密位元組陣列 private static byte[] decrypt(byte[] content, String key) { try { SecretKeySpec secretKeySpec = createKey(key); IvParameterSpec ivParameterSpec = createIV("text1234"); Cipher cipher = Cipher.getInstance(CipherMode); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] result = cipher.doFinal(content); return result; } catch (Exception e) { e.printStackTrace(); } return null; } // 解密(輸出結果為字串), 密文為16進位制的字串 public static String decrypt(String content, String password) { byte[] data = null; try { data = hex2byte(content); } catch (Exception e) { e.printStackTrace(); } data = decrypt(data, password); if (data == null) return null; String result = null; try { result = new String(data, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return result; } /****************************************************************************/ // 位元組陣列轉成16進位制大寫字串 private static String byte2hex(byte[] b) { String tmp = ""; StringBuffer sb = new StringBuffer(b.length * 2); for (int n = 0; n < b.length; n++) { tmp = (Integer.toHexString(b[n] & 0XFF)); if (tmp.length() == 1) { sb.append("0"); } sb.append(tmp); } return sb.toString().toUpperCase(); } // 將16進位制字串轉換成位元組陣列 private static byte[] hex2byte(String inputString) { if (inputString == null || inputString.length() < 2) { return new byte[0]; } inputString = inputString.toLowerCase(); int l = inputString.length() / 2; byte[] result = new byte[l]; for (int i = 0; i < l; ++i) { String tmp = inputString.substring(2 * i, 2 * i + 2); result[i] = (byte) (Integer.parseInt(tmp, 16) & 0xFF); } return result; } }
PKCS5 的工具類,加密之前用Base64編過碼
package com.example.administrator.standardOA.utils;
import android.util.Base64;
import com.alibaba.fastjson.JSONObject;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Duqianlong on 2018/11/15.
*/
public class AesEncryptUtils {
//可配置到Constant中,並讀取配置檔案注入,16位,自己定義
private static final String KEY = "xxxxxxxxxxxxxxxx";
//引數分別代表 演算法名稱/加密模式/資料填充方式
private static final String ALGORITHMSTR = "AES/ECB/PKCS5Padding";
/**
* 加密
* @param content 加密的字串
* @param encryptKey key值
* @return
* @throws Exception
*/
public static String encrypt(String content, String encryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(encryptKey.getBytes(), "AES"));
byte[] b = cipher.doFinal(content.getBytes("utf-8"));
// 採用base64演算法進行轉碼,避免出現中文亂碼
// return Base64.encodeBase64String(b);
String strBase64 = Base64.encodeToString(b , Base64.DEFAULT);
return strBase64;
}
/**
* 解密
* @param encryptStr 解密的字串
* @param decryptKey 解密的key值
* @return
* @throws Exception
*/
public static String decrypt(String encryptStr, String decryptKey) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(128);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(decryptKey.getBytes(), "AES"));
// 採用base64演算法進行轉碼,避免出現中文亂碼
// byte[] encryptBytes = Base64.decodeBase64(encryptStr);
byte[] encryptBytes = Base64.decode(encryptStr,Base64.DEFAULT);
byte[] decryptBytes = cipher.doFinal(encryptBytes);
return new String(decryptBytes);
}
public static String encrypt(String content) throws Exception {
return encrypt(content, KEY);
}
public static String decrypt(String encryptStr) throws Exception {
return decrypt(encryptStr, KEY);
}
public static void main(String[] args) throws Exception {
Map map=new HashMap<String,String>();
map.put("loginName","jtliyajuan");
String content = JSONObject.toJSONString(map);
System.out.println("加密前:" + content);
String encrypt = encrypt(content, KEY);
System.out.println("加密後:" + encrypt);
String decrypt = decrypt(encrypt, KEY);
System.out.println("解密後:" + decrypt);
}
}
使用規則
//加密 pkcs5
public static String encryption(Map<String, String> map) {
String encrypt = "";
Gson gson = new Gson();
try {
encrypt = AesEncryptUtils.encrypt(gson.toJson(map));
} catch (Exception e) {
e.printStackTrace();
}
return encrypt;
}
//解密 pkcs5
public static String decryption(String string) {
String decrypt = "";
try {
decrypt = AesEncryptUtils.decrypt(string);
} catch (Exception e) {
e.printStackTrace();
}
return decrypt;
}
//加密
public static String pkcs7encryption(String string) {
if (!TextUtils.isEmpty(string)) {
String text1 = AESPKCS7PaddingUtils.encrypt(string, UrlConstant.AESkey);//UrlConstant.AESkey:密匙
return text1;
} else {
return "";
}
}
//解密
public static String kpcs7decryption(String string) {
if (!TextUtils.isEmpty(string)) {
String text2 = AESPKCS7PaddingUtils.decrypt(string, UrlConstant.AESkey);//UrlConstant.AESkey:密匙
return text2;
} else {
return "";
}
}