当前位置: 首页 > 面试题库 >

Go中的AES-CTR加密和CryptoJS中的解密

曹鸿风
2023-03-14
问题内容

我在使用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。

谢谢


问题答案:

好的,这是您要解决的问题:

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

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

CTR模式不需要在加密前填充纯文本。
从多个AES块生成的密钥流在XORing之前被修整以匹配纯文本长度。
看起来CryptoJS xor会使用纯文本为其生成密钥流,但不会对其进行修整,因为CryptoJS生成的不带密文的长度padding: CryptoJS.pad.NoPadding总是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>


 类似资料:
  • 我有一个问题解密文本,它是在Go lang加密,使用CryptoJS。 下面是Go代码:https://play.golang.org/p/xcbl48t_in 这里是JS代码:http://jsfidle.net/ltkxm64n/ 这两种方法都能很好地加密和解密,但是当我将base64密文从GO复制到JS(或者反过来)时,它就不起作用了。我还注意到js输出的第一部分与Go输出相同,但在js输出

  • 我有这段代码,它基本上对两条纯文本消息进行加密,然后尝试解密,然后打印。问题是第一条消息恢复得很好,但第二条消息是垃圾。我从本教程下载了这段代码,然后将其修改为使用字符串而不是文件,因为我需要它通过套接字发送加密文本。所以其他endpoint不知道明文的长度,有没有办法找到长度,或者我必须以某种方式将明文的长度与密码一起发送? 现在,我认为解密的中断条件有问题。 另外,main()代码在概念上是否

  • 我之所以问这个问题,是因为两天来我读了很多关于crypto AES加密的帖子,就在我以为我得到了它的时候,我意识到我根本没有得到它。 这个帖子是最接近我的问题,我有完全相同的问题,但它没有得到回答: CryptoJS AES加密与JAVA AES解密值不匹配 我得到的是已经加密的字符串(我得到的代码只是为了看看他们是怎么做的),所以修改加密方式不是一个选项。这就是为什么所有类似的问题对我来说都不是

  • 客户端: 服务器端:

  • 在用于aes加密和解密的python脚本中 但是相同的iv、消息和密钥在python和js中产生不同的加密消息, JavaScript与python解密兼容的问题是什么? 两者都使用了aes.mode_cbc,并且假设两者都使用了Pkcs7填充。硬编码iv现在是随机生成的

  • 问题内容: 我有以下Go代码 输出是 使用以下CryptoJS加密 并且可以用解密 输出是-这是正确的输出 为什么Go会有不同的输出? 问题答案: 请检查您的错误。总是 https://play.golang.org/p/dRLIT51u4I 更具体地说,字节75处的值为,超出了base64可用字符的范围。在ascii中,它是ENQ(查询)字符。至于为什么它最终出现在您的最终base64字符串中,