AES-CTR 在 Go 中加密,在 CryptoJS 中解密
AES-CTR Encrypt in Go and decrypt in CryptoJS
我在使用 CryptoJS 解密在 Go lang 中加密的文本时遇到问题。
这是 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。
谢谢
好的,这是您解决此问题的方法:
-
将无填充 js 添加到源列表:
http://crypto-js.googlecode.com/svn/tags/3.1/build/components/pad-nopadding.js
-
加密/解密时指定参数:
padding: CryptoJS.pad.NoPadding
点击模式在加密之前不需要填充纯文本。
在 XOR 之前,从多个 AES 块生成的密钥流将被修剪以匹配纯文本长度。
看起来 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>
您必须在
编码之前为明文添加填充
例如:
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)
更新:2023
年// CryotoJS CDN
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js" integrity="sha512-E8QSvWZ0eCLGk4km3hxSsNmGWbLtSCSUcewDQPQWZF6pEU8GlT8a5fF32wOl1i8ftdMhssTrF/OhyGWwonTcXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
let config = {
mode: CryptoJS.mode.CTR,
iv: CryptoJS.enc.Utf8.parse('YourInitialVector'),
padding: CryptoJS.pad.NoPadding
};
let dataObjString = JSON.stringify(YourDataObj);
let ciphertext = CryptoJS.AES.encrypt(dataObjString, CryptoJS.enc.Utf8.parse('YourEncryptionKey'), config).toString();
console.log("Encrypted ", ciphertext);
let bytes = CryptoJS.AES.decrypt(ciphertext, CryptoJS.enc.Utf8.parse('YourEncryptionKey'), config);
console.log("Decrypted ", JSON.parse(bytes.toString(CryptoJS.enc.Utf8)));
引用:
- https://cryptojs.gitbook.io/docs/
- https://github.com/brix/crypto-js
- https://cdnjs.com/libraries/crypto-js
希望这会有所帮助。干杯:)
相关文章:
- AES-CTR 在 Go 中加密,在 CryptoJS 中解密
- 使用CryptoJS进行渐进式AES解密
- 可以't使用CryptoJS解密字符串
- 如何在CryptoJS(nodejs/web浏览器)中解密AES 128
- 创建 CryptoJS AES 密码加密器以在 .NET 中解密
- 使用CryptoJS解密图片并将其插入页面
- 如何使用 CryptoJS 解密加密字符串 (SHA512)
- CryptoJS AES CBC 256 解密在明文中间添加了额外的字节
- 填充无效,无法使用CryptoJS 3.1加密和服务器端AesCryptoServiceProvider解密来删除
- 如何在MVC中使用cryptoJs解密代码背后的加密值
- CryptoJS中的加密和mCrypt中的解密工作不正常
- CryptoJS使用密码短语加密AES,但PHP解密需要密钥
- 使用cryptojs解密不起作用
- PHP加密和CryptoJS解密
- CryptoJS解密C#DES加密文件失败
- CryptoJS AES加密和JAVA AES解密值不匹配
- 使用CryptoJS加密和从Objective-C解密
- 使用CryptoJS在Javascript中加密,在Java中解密
- 使用CryptoJS解密文件会产生随机结果
- 使用 PHP 加密;使用 CryptoJS 解密