AES-CTR在Go中加密并在CryptoJS中解密 [英] AES-CTR Encrypt in Go and decrypt in CryptoJS
问题描述
我在使用CryptoJS解密使用Go lang加密的文本时遇到问题。
I have a problem decrypting text, which is encrypted in Go lang, with CryptoJS.
这是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第一部分多。
Both works well encrypting and decrypting, but when I copy the base64 ciphertext from GO to JS (or viceversa), it doesn't work. I also noticed that first part of js output is the same of Go output, but in js output there are more bytes than in Go one.
我的目的是加密GO中的一些文本,然后将Base64密文发送给可以解密它的JS。
My purpose is to encrypt some text in GO, then ship Base64 ciphertext to JS that can decrypt it.
谢谢
推荐答案
好的,您可以采取以下措施解决此问题:
Ok, here is what you do to fix this:
-
添加否 - 将js填充到您的源列表:
http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js
加密/解密时指定参数: padding:CryptoJS.pad.NoPadding
When encrypting/decrypting specify parameter: padding: CryptoJS.pad.NoPadding
CTR模式在加密前不需要填充纯文本。
修剪从多个AES块生成的密钥流以匹配纯文本XORing之前的长度。
看起来CryptoJS生成密钥流到 xor
它用纯文本但不修剪它,因为密文生成的长度是没有填充的CryptoJS:CryptoJS.pad.NoPadding
总是16字节的倍数(与AES块大小完全相同)。
CTR mode doesn't require padding plain text before encrypting.
Keystream generated from multiple AES blocks is trimmed to match plain text length before XORing.
Looks like CryptoJS generates keystream to xor
it with plain text but doesn't trim it, because the length of ciphertext generated by CryptoJS without padding: CryptoJS.pad.NoPadding
is always multiple of 16 bytes (exactly as AES block size).
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>
这篇关于AES-CTR在Go中加密并在CryptoJS中解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!