由于项目改变了加密规则,由原来的三段式加密改为单纯的AES加密,外加MD5验签。所以对加密函数,进行了重写。
后台java代码
-
加密
public static String encryptAES(String data,String key) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(key.getBytes()); kgen.init(128, secureRandom); SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec); logger.info("???????? string:" + data); byte[] encryptedData = cipher.doFinal(data.getBytes("UTF-8")); String hexStr = Base64.encodeBase64String(encryptedData); logger.info("?????ase64?版?: hexStr:" + hexStr); return hexStr; }
-
解密
public static String decryptAES(String data,String key)throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); //kgen.init(128, new SecureRandom(key.getBytes())); SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); secureRandom.setSeed(key.getBytes()); kgen.init(128, secureRandom); SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); logger.info("瑙e?????? string:" + data); byte[] decryptedData = cipher.doFinal(Base64.decodeBase64(data)); String respStr = new String(decryptedData,"UTF-8"); logger.info("瑙e?????? string:" + respStr); return respStr; }
-
MD5
public static String getSingByMD5(String data,String key)throws Exception{ String enStr = data + "|" + key ; String signature = MD5.digestBase64(enStr); return signature; }
前端js代码
前端使用cryptojs加密库
由于之前对加密算法不是很了解,并且项目内的Key并非直接使用,所以在处理KEY的问题上花费了较多的时间。
-
SHA1PRNG
java里可以是经过这个算法处理过的,在前端处理过程中,我们要把原始秘钥经过两次sha1加密,最后取其字符串前32位。 -
加密
function encrypt(data,key) { var realKey = getKey(key); var encrypt = CryptoJS.AES.encrypt(data, CryptoJS.enc.Hex.parse(realKey), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); return encrypt.ciphertext.toString(CryptoJS.enc.Base64); }
-
解密
function decrypt(data,key) { var realKey = getKey(key); var decrypt = CryptoJS.AES.decrypt({ ciphertext: CryptoJS.enc.Base64.parse(data) }, CryptoJS.enc.Hex.parse(realKey), { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); return decrypt.toString(CryptoJS.enc.Utf8); }
-
处理key
function getKey(key) { var realKey = CryptoJS.SHA1(key); realKey = CryptoJS.SHA1(realKey).toString().substring(0, 32); //真正的key return realKey; }
-
MD5
function createMD5(data,key) { var str = data+'|'+key; var md5Str = CryptoJS.MD5(str).toString(CryptoJS.enc.Base64); return md5Str; }
nodejs对应代码
在node中使用自带的crypto库
//配置秘钥
let getkey=()=>"******";
let md5key=()=>"******";
// 加密
let encrypt = (data)=>{
let key = realKey();
let crypted='';
let cipher = crypto.createCipheriv('aes-128-ecb', key, "");
crypted = cipher.update(data, 'utf8', 'binary');
crypted += cipher.final('binary');
crypted = new Buffer(crypted, 'binary').toString('base64');
return crypted;
}
// 解密
let decrypt=(data)=>{
let key = realKey();
let decipher = crypto.createDecipheriv('aes-128-ecb', key,"");
const buf1 = new Buffer(data,"base64").toString('hex');
let decrypted = decipher.update(buf1, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
// 获取key
let realKey=()=>{
let key = getkey();
let keysha1 = crypto.createHash('sha1').update(key).digest('buffer');
let realkey = crypto.createHash('sha1').update(keysha1).digest('hex').substring(0,32);
return new Buffer(realkey,'hex');
}
let encryptmd5=(data)=>{
let key = md5key();
let str = data+"|"+key;
let md5str = crypto.createHash('md5')
.update(str)
.digest('base64');
return md5str;
}
module.exports = {
encrypt,
decrypt,
encryptmd5
};