gpt4 book ai didi

javascript - AES-CTR 在 Go 中加密并在 CryptoJS 中解密

转载 作者:IT王子 更新时间:2023-10-29 01:52:40 35 4
gpt4 key购买 nike

我在使用 CryptoJS 解密在 Go 语言中加密的文本时遇到问题。

这是 Go 代码: https://play.golang.org/p/xCbl48T_iN

package main

import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)

func main() {
key := []byte("1234567890123456")
plaintext := []byte("text can be a random lenght")

block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}

// The IV needs to be unique, but not secure. Therefore it's common to
// include it at the beginning of the ciphertext.
// BTW (only for test purpose) I don't include it

ciphertext := make([]byte, len(plaintext))

iv := []byte{'\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f','\x0f'}

stream := cipher.NewCTR(block, iv)
stream.XORKeyStream(ciphertext, plaintext)

// CTR mode is the same for both encryption and decryption, so we can
// also decrypt that ciphertext with NewCTR.
base := base64.StdEncoding.EncodeToString(ciphertext)
fmt.Printf("encodedHEX: %x\n", ciphertext)
fmt.Printf("encodedBASE: %s\n", base)

plaintext2 := make([]byte, len(plaintext))
stream = cipher.NewCTR(block, iv)
stream.XORKeyStream(plaintext2, ciphertext)

fmt.Printf("decoded: %s\n", plaintext2)
}

JS代码如下: http://jsfiddle.net/Ltkxm64n/

var key = CryptoJS.enc.Hex.parse('31323334353637383930313233343536');
var iv = CryptoJS.enc.Hex.parse('0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f');
var encrypted = CryptoJS.AES.encrypt("text can be a random lenght", key, {
mode: CryptoJS.mode.CTR,
iv: iv
});

console.log(encrypted.ciphertext.toString());
console.log(encrypted.toString());

var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
mode: CryptoJS.mode.CTR,
iv: iv
});
console.log(decrypted.toString(CryptoJS.enc.Utf8));
// text can be a random lenght

两者都可以很好地加密和解密,但是当我将 base64 密文从 GO 复制到 JS(或反之亦然)时,它不起作用。我还注意到 js 输出的第一部分与 Go 输出相同,但是 js 输出中的字节数比 Go 多。

我的目的是在GO中加密一些文本,然后将Base64密文发送给可以解密的JS。

谢谢

最佳答案

好的,这是解决此问题的方法:

  1. 将无填充 js 添加到您的源列表:http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js

  2. 加密/解密时指定参数:padding: CryptoJS.pad.NoPadding

CTR模式不需要在加密前填充明文。
从多个 AES block 生成的 key 流在 XORing 之前被 trim 以匹配纯文本长度。
看起来 CryptoJS 生成 key 流以 xor 它与纯文本但不 trim 它,因为 CryptoJS 生成的密文长度没有 padding: CryptoJS.pad.NoPadding 总是16 字节的倍数(正好是 AES block 大小)。

var key = CryptoJS.enc.Hex.parse('31323334353637383930313233343536');
var iv = CryptoJS.enc.Hex.parse('0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f');
var encrypted = CryptoJS.AES.encrypt("text can be a random lenght", key, {
mode: CryptoJS.mode.CTR,
iv: iv,
padding: CryptoJS.pad.NoPadding
});

document.getElementById("id").innerHTML = encrypted.ciphertext.toString();
document.getElementById("id2").innerHTML = encrypted.toString();

var decrypted = CryptoJS.AES.decrypt(encrypted, key, {
mode: CryptoJS.mode.CTR,
iv: iv,
padding: CryptoJS.pad.NoPadding
});
document.getElementById("decrypt").innerHTML = decrypted.toString(CryptoJS.enc.Utf8); // text can be a random lenght
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/mode-ctr.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js"></script>
<p> Ciphertext in HEX: </p>
<p id="id"> </p>
<p> Ciphertext in BASE64: </p>
<p id="id2"> </p>
<p> PlainText: </p>
<p id="decrypt"></p>

关于javascript - AES-CTR 在 Go 中加密并在 CryptoJS 中解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36909746/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com