不同编程语言对于加密的处理可能不一样,最近在做一个区块链项目,有使用go语言和nodejs语言实现AES 256 CBC 算法。可以实现nodejs加密后 用go解密
go 实现
package KMS
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"fmt"
"encoding/base64"
"encoding/hex"
"github.com/gin-gonic/gin"
)
type RequestInfostruct {
Authorization string`json:"authorization"`
c *gin.Context
}
/*
加密,首先是从kms获取数据密钥和向量等,然后调用aes接口加密和解密orgId 组织id
data 明文数据*/
func Encrypt(kmshostname,kmsport,orgId string,data []byte,req RequestInfo) (string,error) {
fmt.Println("Encrypt start =======================")
//var KMSkey= GetKeyAndIVSync(kmshostname,kmsport,orgId)
resData,err := GetKeyAndIVSync(kmshostname,kmsport,orgId,req)
if err!=nil {
fmt.Println("Encrypt GetKeyAndIVSync fail",err)
return "",err
}
fmt.Println("KMS KEY resData",resData)
key,_ := base64.StdEncoding.DecodeString(resData.DataKey)
iv,_ := base64.StdEncoding.DecodeString(resData.IV)
var enc=AES_CBC_Encrypt([]byte(data),key,iv)
fmt.Println("Encrypt end =======================")
return hex.EncodeToString(enc),nil
}
/*
解密,首先是从kms获取数据密钥和向量等,然后调用aes接口加密和解密orgId 组织id
data 密文数据*/
func Decrypt(kmshostname,kmsport,orgId string,data []byte, req RequestInfo) (string,error) {
fmt.Println("Encrypt start =======================")
//var KMSkey=GetKeyAndIVSync(kmshostname,kmsport,orgId)
resData,err :=GetKeyAndIVSync(kmshostname,kmsport,orgId,req)
if err!=nil {
fmt.Println("Encrypt GetKeyAndIVSync fail",err)
return "",err
}
fmt.Println("KMS KEY resData",resData)
key,_ := base64.StdEncoding.DecodeString(resData.DataKey)
iv,_ := base64.StdEncoding.DecodeString(resData.IV)
var dec=AES_CBC_Decrypt([]byte(data),key,iv)
fmt.Println("Encrypt start =======================")
return hex.EncodeToString(dec),nil
}
//对明文进行填充
func Padding(plainText []byte,blockSize int) []byte{
//计算要填充的长度
n:= blockSize-len(plainText)%blockSize
//对原来的明文填充n个n
temp:=bytes.Repeat([]byte{byte(n)},n)
plainText=append(plainText,temp...)
return plainText
}
//对密文删除填充
func UnPadding(cipherText []byte) []byte{
//取出密文最后一个字节end
end:=cipherText[len(cipherText)-1]
//删除填充
cipherText=cipherText[:len(cipherText)-int(end)]
return cipherText
}
//AEC加密(CBC模式)
func AES_CBC_Encrypt(plainText []byte,key,iv []byte) []byte{
//指定加密算法,返回一个AES算法的Block接口对象
block,err:=aes.NewCipher(key)
if err!=nil{
panic(err)
}
//进行填充
plainText=Padding(plainText,block.BlockSize())
//指定分组模式,返回一个BlockMode接口对象
blockMode:=cipher.NewCBCEncrypter(block,iv)
//加密连续数据库
cipherText:=make([]byte,len(plainText))
blockMode.CryptBlocks(cipherText,plainText)
//返回密文
return cipherText
}
//AEC解密(CBC模式)
func AES_CBC_Decrypt(cipherText []byte,key,iv []byte) []byte{
//指定解密算法,返回一个AES算法的Block接口对象
block,err:=aes.NewCipher(key)
if err!=nil{
panic(err)
}
//指定分组模式,返回一个BlockMode接口对象
blockMode:=cipher.NewCBCDecrypter(block,iv)
//解密
plainText:=make([]byte,len(cipherText))
blockMode.CryptBlocks(plainText,cipherText)
//删除填充
plainText=UnPadding(plainText)
return plainText
}
nodejs 实现
const crypto =require('crypto');
const algorithm ='aes-256-cbc';
const key1 =crypto.randomBytes(32);
const iv1 =crypto.randomBytes(16);
/*
加密数据
@text 明文
@key 数据密钥
@iv 向量
@return value null for error, encrypted text for success
*/
function encrypt(text,key,iv) {
try{
let cipher =crypto.createCipheriv('aes-256-cbc',Buffer.from(key), iv);
let encrypted =cipher.update(text);
encrypted =Buffer.concat([encrypted,cipher.final()]);
return encrypted.toString('hex');
}catch (e) {
return null
}
}
/*
解密
@text 密文
@key 数据密钥
@iv 向量
*/
function decrypt(text,key,iv) {
//let iv = Buffer.from(text.iv, 'hex');
try{
let encryptedText =Buffer.from(text,'hex');
let decipher =crypto.createDecipheriv('aes-256-cbc',Buffer.from(key), iv);
let decrypted =decipher.update(encryptedText);
decrypted =Buffer.concat([decrypted,decipher.final()]);
return decrypted.toString();
}catch (e) {
console.log(e)
return null
}
}
/*
console.log("============================================================")
var hw = encrypt("中文测试Some serious stuff",key1,iv1)
console.log(hw)
console.log(decrypt(hw,key1,iv1))
console.log("============================================================")
*/
module.exports.encrypt=encrypt
module.exports.decrypt=decrypt