前后端 crypto-js aes 加解密
前言
项目中需要对敏感数据进行加密解密,比如身份证号,手机号码等关键信息,前后端都需要进行接口加密处理的情况,
此处使用的是crypto-js aes,有两种方式
安装包的使用案例
使用cdn资源
一、前端实现
1.安装包
(1)npm 安装
npm install crypto-js --save
(2) 引入
const CryptoJS = require('crypto-js');
(3)使用
function getAesString(data,key,iv){//加密
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted =CryptoJS.AES.encrypt(data,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return encrypted.toString(); //返回的是base64格式的密文
}
function getDAesString(encrypted,key,iv){//解密
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var decrypted =CryptoJS.AES.decrypt(encrypted,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
function getAES(data){ //加密
var key = 'whsiwyw'; //密钥
var iv = '1234567812345678';
var encrypted =getAesString(data,key,iv); //密文
return encrypted;
}
function getDAes(data){//解密
var key = 'whsiwyw'; //密钥
var iv = '1234567812345678';
var decryptedStr =getDAesString(data,key,iv);
return decryptedStr;
}
//J1RQj2IOLeIVMpjZzYtkEg==
// var mypwd = getAES('liyanpeng123456')
// console.log(mypwd)
// alert(mypwd)
var resmypwd = getDAes('J1RQj2IOLeIVMpjZzYtkEg==')
console.log(resmypwd)
alert(resmypwd)
2.cdn使用
(1)引入资源
<!-- 引入 CDN Crypto.js 开始 AES加密 注意引入顺序 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/enc-base64.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/md5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/evpkdf.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/cipher-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/aes.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/pad-pkcs7.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/mode-ecb.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/enc-utf8.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/enc-hex.min.js"></script>
<!-- 引入 CDN Crypto.js 结束 -->
(2)使用
function getAesString(data,key,iv){//加密
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var encrypted =CryptoJS.AES.encrypt(data,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return encrypted.toString(); //返回的是base64格式的密文
}
function getDAesString(encrypted,key,iv){//解密
var key = CryptoJS.enc.Utf8.parse(key);
var iv = CryptoJS.enc.Utf8.parse(iv);
var decrypted =CryptoJS.AES.decrypt(encrypted,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
function getAES(data){ //加密
var key = 'whsiwyw'; //密钥
var iv = '1234567812345678';
var encrypted =getAesString(data,key,iv); //密文
return encrypted;
}
function getDAes(data){//解密
var key = 'whsiwyw'; //密钥
var iv = '1234567812345678';
var decryptedStr =getDAesString(data,key,iv);
return decryptedStr;
}
//J1RQj2IOLeIVMpjZzYtkEg==
// var mypwd = getAES('liyanpeng123456')
// console.log(mypwd)
// alert(mypwd)
var resmypwd = getDAes('J1RQj2IOLeIVMpjZzYtkEg==')
console.log(resmypwd)
alert(resmypwd)
二、后端实现
//密钥 (需要前端和后端保持一致)
private const val KEY = "········"
//算法
private const val ALGORITHMSTR = "········"
val log = LoggerFactory.getLogger(this.javaClass)
/**
* aes解密
*
* @param encrypt 内容
* @return
* @throws Exception
*/
fun aesDecrypt(encrypt: String?): String? {
return try {
aesDecrypt(encrypt, KEY)
} catch (e: Exception) {
e.printStackTrace()
""
}
}
/**
* aes加密
*
* @param content
* @return
* @throws Exception
*/
fun aesEncrypt(content: String): String {
return try {
aesEncrypt(content, KEY)
} catch (e: Exception) {
e.printStackTrace()
""
}
}
/**
* 将byte[]转为各种进制的字符串
*
* @param bytes byte[]
* @param radix 可以转换进制的范围,从Character.MIN_RADIX到Character.MAX_RADIX,超出范围后变为10进制
* @return 转换后的字符串
*/
fun binary(bytes: ByteArray?, radix: Int): String {
return BigInteger(1, bytes).toString(radix) // 这里的1代表正数
}
/**
* base 64 encode
*
* @param bytes 待编码的byte[]
* @return 编码后的base 64 code
*/
fun base64Encode(bytes: ByteArray?): String {
return Base64.encodeBase64String(bytes)
}
/**
* base 64 decode
*
* @param base64Code 待解码的base 64 code
* @return 解码后的byte[]
* @throws Exception
*/
@Throws(Exception::class)
fun base64Decode(base64Code: String?): ByteArray? {
return if (StringUtils.isEmpty(base64Code)) null else BASE64Decoder().decodeBuffer(base64Code)
}
/**
* AES加密
*
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的byte[]
* @throws Exception
*/
@Throws(Exception::class)
fun aesEncryptToBytes(content: String, encryptKey: String): ByteArray {
val kgen = KeyGenerator.getInstance("AES")
kgen.init(128)
val cipher = Cipher.getInstance(ALGORITHMSTR)
cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(encryptKey.toByteArray(), "AES"))
return cipher.doFinal(content.toByteArray(charset("utf-8")))
}
/**
* AES加密为base 64 code
*
* @param content 待加密的内容
* @param encryptKey 加密密钥
* @return 加密后的base 64 code
* @throws Exception
*/
@Throws(Exception::class)
fun aesEncrypt(content: String, encryptKey: String): String {
return base64Encode(aesEncryptToBytes(content, encryptKey))
}
/**
* AES解密
*
* @param encryptBytes 待解密的byte[]
* @param decryptKey 解密密钥
* @return 解密后的String
* @throws Exception
*/
@Throws(Exception::class)
fun aesDecryptByBytes(encryptBytes: ByteArray?, decryptKey: String): String {
val kgen = KeyGenerator.getInstance("AES")
kgen.init(128)
val cipher = Cipher.getInstance(ALGORITHMSTR)
cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(decryptKey.toByteArray(), "AES"))
val decryptBytes = cipher.doFinal(encryptBytes)
return String(decryptBytes)
}
/**
* 将base 64 code AES解密
*
* @param encryptStr 待解密的base 64 code
* @param decryptKey 解密密钥
* @return 解密后的string
* @throws Exception
*/
@JvmStatic
fun aesDecrypt(encryptStr: String?, decryptKey: String): String? {
return try {
log.info("aesDecrypt", aesDecryptByBytes(base64Decode(encryptStr), decryptKey))
if (StringUtils.isEmpty(encryptStr)) null else aesDecryptByBytes(base64Decode(encryptStr), decryptKey)
} catch (e: Exception) {
log.error("aesDecrypt is error ! '${e.message}'" )
return ""
}
}
/**
* 测试
*/
@Throws(Exception::class)
@JvmStatic
fun main(args: Array<String>) {
val content = ""
println("加密前:$content")
// System.out.println("加密密钥和解密密钥:" + KEY);
val encrypt = aesEncrypt(content, "········")
println("加密后:$encrypt")
val decrypt = aesDecrypt("········", "········")
println("解密后:$decrypt")
}
总结
前后端 crypto-js aes 加解密实现。
参考文章:https://www.jianshu.com/p/90540249747d;https://www.jianshu.com/p/a47477e8126a;https://www.cnblogs.com/lz2017/p/8046816.html