1 回答
TA贡献1719条经验 获得超6个赞
代码基本没问题,只有几个小问题:
CryptoJS 不会自动禁用流密码模式(如 CTR)的默认 PKCS7 填充。因此,必须在 Go 代码中应用 PKCS7 填充。
由于CryptoJS代码使用内部的PBKDF,所以解密需要OpenSSL格式(即Salted__的ASCII编码后跟8字节salt和实际密文),十六进制编码。因此 Go 代码必须相应地格式化和编码数据。
CryptoJS在使用内部 PBKDF 时派生密钥和 IV 。因此,在 CryptoJS 代码中,指定的 IV在解密过程中被忽略。因此,在 Go 代码中,可以指定任何IV。
以下代码对应于您的代码,由 PKCS#7 填充和结果的格式/编码扩展(考虑代码中的注释)。请注意,与您的代码一样,为了简单起见,使用了硬编码盐,但实际上出于安全原因,必须应用随机生成的盐:
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"fmt"
evp "github.com/walkert/go-evp"
"github.com/zenazn/pkcs7pad"
)
func main() {
rawKey := "46ca2a49c8074dadb99843f6b86c5975"
data := pkcs7pad.Pad([]byte("the quick brown fox jumps over the lazy dog"), 16) // 1. Pad the plaintext with PKCS#7
fmt.Println("padded data: ", hex.EncodeToString(data))
encryptedData := encrypt(rawKey, data)
fmt.Println("encrypted data: ", encryptedData)
}
func encrypt(rawKey string, plainText []byte) string {
salt := []byte("ABCDEFGH") // hardcoded at the moment
// Gets key and IV from raw key.
key, iv := evp.BytesToKeyAES256CBCMD5([]byte(salt), []byte(rawKey))
// Create new AES cipher block
block, err := aes.NewCipher(key)
if err != nil {
return err.Error()
}
cipherText := make([]byte, len(plainText))
// Encrypt.
encryptStream := cipher.NewCTR(block, iv)
encryptStream.XORKeyStream(cipherText, plainText)
ivHex := hex.EncodeToString(iv)
encryptedDataHex := hex.EncodeToString([]byte("Salted__")) + hex.EncodeToString(salt) + hex.EncodeToString(cipherText) // 2. Apply the OpenSSL format, hex encode the result
return ivHex + ":" + encryptedDataHex // 3. Any value for ivHex can be used here, e.g. "00000000000000000000000000000000"
}
输出是:
padded data: 74686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f670505050505
encrypted data: 3a010df5e7985f2d8b0c00e3a096347f:53616c7465645f5f41424344454647486036327f61cf3050fddd6ea76325148c81e170a63b514b8818afbbb894c874c87cc4c865300c7b2d0e0fd82826f3d3c5
可以使用遗留代码解密此密文:
const decrypt = function (rawKey, encryptedData) {
const split = encryptedData.split(':');
if (split.length < 2) return '';
const reb64 = CryptoJS.enc.Hex.parse(split[1]);
const bytes = reb64.toString(CryptoJS.enc.Base64);
const hash = CryptoJS.AES.decrypt(bytes, rawKey, {
iv: split[0], // This is ignored if the internal PBKDF is used
mode: CryptoJS.mode.CTR
});
const plain = hash.toString(CryptoJS.enc.Utf8);
return plain;
}
const rawKey = '46ca2a49c8074dadb99843f6b86c5975';
const encryptedData = '3a010df5e7985f2d8b0c00e3a096347f:53616c7465645f5f41424344454647486036327f61cf3050fddd6ea76325148c81e170a63b514b8818afbbb894c874c87cc4c865300c7b2d0e0fd82826f3d3c5';
const decyptedData = decrypt(rawKey, encryptedData);
document.getElementById("pt").innerHTML = "decrypted data: " + decyptedData;
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
<p style="font-family:'Courier New', monospace;" id="pt"></p>
- 1 回答
- 0 关注
- 499 浏览
添加回答
举报