用beego写了个服务器,为了减少数据暴露,前端js对数据加密后再传到服务器。之后使用由服务器取数据做运算,不再暴露给客户端。js不是很熟悉,所以aes加密这块调试了些时间。
js加密部分
用的库是crypto-js
// AES加密
function AESEncrypto(str, key){
key = PaddingLeft(key, 16);
key = CryptoJS.enc.Utf8.parse(key);
// 加密结果返回的是CipherParams object类型
var encrypted = CryptoJS.AES.encrypt(str, key, {
iv: key,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// ciphertext是密文,toString()内传编码格式,比如Base64,这里用了16进制
return encrypted.ciphertext.toString(CryptoJS.enc.Hex);
}
// 左填充方法
function PaddingLeft(key, length){
pkey= key.toString();
var l = pkey.length;
if (l < length) {
pkey = new Array(length - l + 1).join('0') + pkey;
}else if (l > length){
pkey = pkey.slice(length);
}
return pkey;
}
最初把左填充放在了转Utf8之前,调试许久。。。
Go解密部分
// 上面js代码最后返回的是16进制
// 所以收到的数据hexText还需要用hex.DecodeString(hexText)转一下,这里略了
func Decrypt(ciphertext, key []byte) ([]byte, error) {
pkey := PaddingLeft(key, '0', 16)
block, err := aes.NewCipher(pkey) //选择加密算法
if err != nil {
return nil, err
}
blockModel := cipher.NewCBCDecrypter(block, pkey)
plantText := make([]byte, len(ciphertext))
blockModel.CryptBlocks(plantText, []byte(ciphertext))
plantText = PKCS7UnPadding(plantText, block.BlockSize())
return plantText, nil
}
func PKCS7UnPadding(plantText []byte, blockSize int) []byte {
length := len(plantText)
unpadding := int(plantText[length-1])
return plantText[:(length - unpadding)]
}
func PaddingLeft(ori []byte, pad byte, length int) []byte {
if len(ori) >= length {
return ori[:length]
}
pads := bytes.Repeat([]byte{pad}, length-len(ori))
return append(pads, ori...)
}
TODO
经验不足,写的不严谨。看开源的加密代码,加完密还要把数组清空,尽管只是个局部变量。