问题描述
我想在 JavaScript 中翻译 Go DES 代码
这是我的 Go 代码,使用 des zeropadding 加密。现在想用javascript来实现同样的功能,但是试了很多次,结果总是不对。
package zeropadding
import (
"crypto/cipher"
"crypto/des"
"encoding/hex"
"fmt"
"strings"
)
func main() {
text := DesEncrypt([]byte("12345678"),[]byte("12345678"))
fmt.Println(strings.toupper(hex.EncodetoString(text)))
}
func DesEncrypt(origData,key []byte) []byte {
iv := []byte{0,0}
block,err := des.NewCipher(key)
if err != nil {
return nil
}
origData = ZeroPadding(origData)
blockMode := cipher.NewCBCEncrypter(block,iv)
crypted := make([]byte,len(origData))
blockMode.CryptBlocks(crypted,origData)
return crypted
}
func ZeroPadding(in []byte) []byte {
length := len(in)
blockCount := length / 8
out := make([]byte,(blockCount+1)*8)
var i int
for i = 0; i < length; i++ {
out[i] = in[i]
}
return out
}
如何使用javascript来做到这一点
const CryptoJS = require('./crypto-js.min')
function encryptByDES(message,key,iv) {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var ivHex = CryptoJS.enc.Utf8.parse(iv);
encrypted = CryptoJS.DES.encrypt(message,keyHex,{
iv: ivHex,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.ZeroPadding
}
);
return encrypted.ciphertext.toString();
}
console.log(encryptByDES("12345678","12345678",0))
我使用 lib crypto-js
,使用模式 CryptoJS.mode.CBC
和填充 CryptoJS.pad.ZeroPadding
,但结果与 Go 代码输出不相等。
解决方法
看起来你的 go 代码和你的 javascript 都存在问题,这可能是令人困惑的事情。 (警告 - 我远不是加密专家!)。
去
零填充应该将 [] 字节填充为块大小的倍数(在您的情况下为 8),但实际上,如果输入长度为 8 字节,您将填充为 16 字节。试试:
blockCount := (length - 1) / blockSize
Javascript
您将 IV 作为数字提供,但随后将其转换为 utf8。让我们来反映你在做什么:
var ivHex = CryptoJS.enc.Hex.parse(iv);
并将 IV 以十六进制形式传入:
console.log(encryptByDES("1234567890","12345678","0000000000000000"))
,
另一种方法是使用 WebAssembly(参见 webassembly.org),考虑到:
-
你可以将你的 Go 项目编译成 wasm
GOOS=js GOARCH=wasm go build -o main.wasm
(有关更多最佳做法,请参阅 Best Practices for WebAssembly using GoLang (1.15+) 中的“Cesar William Alvarenga”)