版权声明:本博客主要用于学习、工作总结、技术分享等。因博主能力有限,有误之处还望指正。博客大多为本人原创,如有借鉴他们博文涉及侵权等行为,还望告知,立即删除。 https://blog.csdn.net/weixin_43532530/article/details/83547398
前言
数据加密技术一直是一个非常神秘、高深的技术。本人刚刚开始着手数据加密的学习,更多是对数据加密技术的应用,至于说原理,真的没有足够高的造诣还真是琢磨不够。
首先先进加密技术主要分为两类,一类是对称加密(可逆加密),另一类则为非对称加密(不可逆加密)。可以从字面上理解,可逆加密就是数据进行加密后还可以解密得到原来的数据,不可逆加密就是数据进行加密后无法得到原来的数据。
当然有个更形象的说法:
对称加密和解密都使用同一把秘钥,这种加密方法称为对称加密,称为单密钥加密。
简单理解为:加密解密都是同一把钥匙。
对称(可逆)加密算法如: DES 、 AES等
非对称加密算法需要两个密钥:公钥(publickey)和私钥(privatekey)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密;如果用私钥对数据进行加密,那么只有用对应的公钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
简单理解为:加密和解密是不同的钥匙。
非堆成(不可逆)加密如: RSA(安全散列算法)
好了,本文仅仅是说明技术应用的,至于算法思想与算法原理请自行深入学习。
加密传输实现
前端加密
在这里,我们通过引入第三方AES库实现。aes.js文件点此下载
不想下载的直接copy这里:
不好意思 代码太多了
前端加密
/**
* @param word
* @returns {*}
*/
function encrypt(data){
var key = CryptoJS.enc.Utf8.parse("abcdefgabcdefg12");
var srcs = CryptoJS.enc.Utf8.parse(data);
var encrypted = CryptoJS.AES.encrypt(srcs, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
return encrypted.toString();
}
/**
* 解密
* @param word
* @returns {*}
*/
function decrypt(data){
var key = CryptoJS.enc.Utf8.parse("abcdefgabcdefg12");
var decrypt = CryptoJS.AES.decrypt(data, key, {mode:CryptoJS.mode.ECB,padding: CryptoJS.pad.Pkcs7});
return CryptoJS.enc.Utf8.stringify(decrypt).toString();
}
$("#login").click(function () {
// alert(encrypt($("#username").val()+" "+encrypt($("#password").val())));
$.ajax({
method:'POST',
url:'/login',
dataType:'json',
async: true,
data: {
'username': encrypt($("#username").val()),
'password': encrypt($("#password").val())
},
success: function (data) {
console.log(data)
if(data.code==200){
location.href="/"
}
}
})
})
后端解密
我们把解密所需的函数封装为一个工具类
package com.gllue.carpo.web.util
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpec
import org.apache.commons.codec.binary.Base64
import org.springframework.util.StringUtils
import javax.crypto.KeyGenerator;
class AESUtil{
companion object {
//密钥 (需要前端和后端保持一致)
private val KEY = "abcdefgabcdefg12"
//算法
private val ALGORITHMSTR = "AES/ECB/PKCS5Padding"
fun aesDecrypt(encryptStr: String): String? {
return aesDecrypt(encryptStr, KEY)
}
/**
* 将base 64 code AES解密
* @param encryptStr 待解密的base 64 code
* @param decryptKey 解密密钥
* @return 解密后的string
* @throws Exception
*/
@Throws(Exception::class)
fun aesDecrypt(encryptStr: String, decryptKey: String): String? {
return if (StringUtils.isEmpty(encryptStr)) null else aesDecryptByBytes(base64Decode(encryptStr), decryptKey)
}
/**
* 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 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 Base64.decodeBase64(base64Code)
}
}
}
接受不了加密数据后进行解密
@ResponseBody
@RequestMapping(value = "/login",method = arrayOf(RequestMethod.POST))
fun loginCheck(@RequestParam("username") username: String,@RequestParam("password") password: String, response: HttpServletResponse, request: HttpServletRequest): ResponseVO<Any>{
println("${username}**********${password}")
println("解密后数据: string:${AESUtil.aesDecrypt(password)}")
request.session.setAttribute("username",username)
return ResponseVO(200)
}