AES-CTR在Go中加密并在CryptoJS中解密 [英] AES-CTR Encrypt in Go and decrypt in CryptoJS

查看:126
本文介绍了AES-CTR在Go中加密并在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:


  1. 添加否 - 将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆