Go语言和前端的DES加密解密
Go语言和前端的DES加密解密
前端实现
安装加密包
npm install crypto-js
封装加密
des.js
import CryptoJS from '../node_modules/crypto-js/crypto-js.js'
// DES加密
export const encryptDes = (message, key) => {
const keyHex = CryptoJS.enc.Utf8.parse(key);
const encrypted = CryptoJS.DES.encrypt(message, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
// DES解密
export const decryptDes = (ciphertext, key) => {
const keyHex = CryptoJS.enc.Utf8.parse(key);
// direct decrypt ciphertext
const decrypted = CryptoJS.DES.decrypt({
ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
}, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
加密
import { encryptDes, decryptDes } from '@/common/des.js' // 引用路径根据自己的文件结构而定
encryptDes('要加密的数据', '加密的key')
decryptDes('要解密的数据', '解密的key')
go语言实现
封装加密
crypt.go
package crypt
import (
"crypto/cipher"
"crypto/des"
"encoding/base64"
"errors"
)
// EncryptDES DES加密
// message: 明文
// key: 8字节密钥
// 返回Base64编码的密文和可能的错误
func EncryptDES(message string, key string) (string, error) {
if len(key) != 8 {
return "", errors.New("DES key must be 8 bytes")
}
// 创建DES cipher
block, err := des.NewCipher([]byte(key))
if err != nil {
return "", err
}
// 创建ECB模式的加密器
mode := NewECBEncrypter(block)
// 对明文进行PKCS7填充
plaintext := pkcs7Padding([]byte(message), block.BlockSize())
// 创建密文缓冲区
ciphertext := make([]byte, len(plaintext))
// 加密
mode.CryptBlocks(ciphertext, plaintext)
// 返回Base64编码的密文
return base64.StdEncoding.EncodeToString(ciphertext), nil
}
// DecryptDES DES解密
// ciphertext: Base64编码的密文
// key: 8字节密钥
// 返回解密后的明文和可能的错误
func DecryptDES(ciphertext string, key string) (string, error) {
if len(key) != 8 {
return "", errors.New("DES key must be 8 bytes")
}
// 解码Base64密文
cipherBytes, err := base64.StdEncoding.DecodeString(ciphertext)
if err != nil {
return "", err
}
// 创建DES cipher
block, err := des.NewCipher([]byte(key))
if err != nil {
return "", err
}
// 创建ECB模式的解密器
mode := NewECBDecrypter(block)
// 确保密文长度是8的倍数
if len(cipherBytes)%8 != 0 {
return "", errors.New("ciphertext is not a multiple of the block size")
}
// 创建明文缓冲区
plaintext := make([]byte, len(cipherBytes))
// 解密
mode.CryptBlocks(plaintext, cipherBytes)
// 去除PKCS7填充
unpadded := pkcs7UnPadding(plaintext)
return string(unpadded), nil
}
// ECBEncrypter 实现ECB模式的加密器
type ECBEncrypter struct {
b cipher.Block
blockSize int
}
// NewECBEncrypter 创建一个新的ECB加密器
func NewECBEncrypter(b cipher.Block) *ECBEncrypter {
return &ECBEncrypter{
b: b,
blockSize: b.BlockSize(),
}
}
// CryptBlocks 实现ECB模式的加密
func (x *ECBEncrypter) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("input not full blocks")
}
if len(dst) < len(src) {
panic("output smaller than input")
}
for len(src) > 0 {
x.b.Encrypt(dst, src[:x.blockSize])
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}
// ECBDecrypter 实现ECB模式的解密器
type ECBDecrypter struct {
b cipher.Block
blockSize int
}
// NewECBDecrypter 创建一个新的ECB解密器
func NewECBDecrypter(b cipher.Block) *ECBDecrypter {
return &ECBDecrypter{
b: b,
blockSize: b.BlockSize(),
}
}
// CryptBlocks 实现ECB模式的解密
func (x *ECBDecrypter) CryptBlocks(dst, src []byte) {
if len(src)%x.blockSize != 0 {
panic("input not full blocks")
}
if len(dst) < len(src) {
panic("output smaller than input")
}
for len(src) > 0 {
x.b.Decrypt(dst, src[:x.blockSize])
src = src[x.blockSize:]
dst = dst[x.blockSize:]
}
}
// pkcs7Padding 添加PKCS7填充
func pkcs7Padding(origData []byte, blockSize int) []byte {
padding := blockSize - len(origData)%blockSize
padtext := make([]byte, len(origData)+padding)
copy(padtext, origData)
for i := len(origData); i < len(padtext); i++ {
padtext[i] = byte(padding)
}
return padtext
}
// pkcs7UnPadding 去除PKCS7填充
func pkcs7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
解密
plainText, err := crypt.DecryptDES("vxa4TNMOWDlqwBnhYGD/6A==", "12345678")