我在用CryptoJS加密的Go lang中解密文本时遇到了问题。
下面是Go代码: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。
谢谢
发布于 2016-04-28 11:53:58
好的,下面是解决这个问题的方法:
http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.jspadding: CryptoJS.pad.NoPaddingCTR模式在加密前不需要填充纯文本。
从多个AES块生成的密钥流被裁剪以匹配XORing之前的纯文本长度。
看起来CryptoJS用纯文本生成密钥流到xor,但没有修剪它,因为不带padding: CryptoJS.pad.NoPadding的CryptoJS生成的密文长度总是16字节的倍数(与AES块大小完全相同)。
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>
发布于 2016-04-28 11:36:43
在对明文进行编码之前,必须向明文添加填充内容。
例如:
func addPadding(data []byte, blocksize int) []byte {
padSize := len(data) % blocksize
if padSize == 0 {
return data
}
padSize = blocksize - padSize
return append(data, bytes.Repeat([]byte{byte(padSize)}, padSize)...)
}
//in main
plaintext := []byte("text can be a random lenght")
plaintext = addPadding(plaintext, aes.BlockSize)https://stackoverflow.com/questions/36909746
复制相似问题