CryptoJS.AES.encrypt Go 等价物

问题描述 投票:0回答:1

我试图在 golang 中编码字符串等同于 javascript cryptoJs 库,但是当使用 golang 和 javascript 加密时结果不一样!

这段代码在 js 中创建了一个 128 位密码

javascript代码:

let message = 'I need encrypt this message with CryptoJS.AES.encrypt and decrypt with Golang AES package';
let key = 'key created dynamically and key.length not in AES length standard';


// convert to word array
message = CryptoJS.enc.Utf8.parse(message)
key = CryptoJS.enc.Utf8.parse(key)

// create hash
const hash = CryptoJS.AES.encrypt(message, key, {
        mode: CryptoJS.mode.ECB,
        padding: CryptoJS.pad.ZeroPadding
    }).ciphertext.toString(CryptoJS.enc.Hex)

在此代码段中,cryptoJs aes 加密函数接受不同大小的密钥字符串,但在 golang aes 包中只接受标准大小,如 16,32。

go aes cryptojs
1个回答
0
投票

AES 加密需要 128、192 或 256 位(16、24 或 32 字节)的固定长度密钥。如果要使用任意大小的密钥,可以使用诸如 PBKDF2(基于密码的密钥派生函数 2)的密钥派生函数从可变长度密钥派生出固定长度的密钥。这是一个如何在 Golang 和 Node.js 中执行此操作的示例:

戈朗

package main

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "crypto/sha256"
    "encoding/hex"
    "fmt"
    "io"
    "golang.org/x/crypto/pbkdf2"
)

func encrypt(text string, key []byte) string {
    salt := make([]byte, 8)
    if _, err := io.ReadFull(rand.Reader, salt); err != nil {
        panic(err)
    }

    derivedKey := pbkdf2.Key(key, salt, 4096, 32, sha256.New)

    block, err := aes.NewCipher(derivedKey)
    if err != nil {
        panic(err.Error())
    }

    ciphertext := make([]byte, aes.BlockSize+len(text))
    iv := ciphertext[:aes.BlockSize]
    if _, err := io.ReadFull(rand.Reader, iv); err != nil {
        panic(err)
    }

    stream := cipher.NewCFBEncrypter(block, iv)
    stream.XORKeyStream(ciphertext[aes.BlockSize:], []byte(text))

    return fmt.Sprintf("%x%x", salt, ciphertext)
}

func main() {
    key := []byte("a very secret key")
    message := "Hello World!"
    encryptedMessage := encrypt(message, key)
    fmt.Println(encryptedMessage)
}

节点.js

const crypto = require('crypto');

function decrypt(encrypted, key) {
  const encryptedBuffer = Buffer.from(encrypted, 'hex');
  const salt = encryptedBuffer.slice(0, 8);
  const iv = encryptedBuffer.slice(8, 24);
  const encryptedText = encryptedBuffer.slice(24);
  const derivedKey = crypto.pbkdf2Sync(key, salt, 4096, 32, 'sha256');
  const decipher = crypto.createDecipheriv('aes-256-cfb', derivedKey, iv);
  let decrypted = decipher.update(encryptedText);
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString();
}

const key = 'a very secret key';
const encryptedMessage = '...'; // The encrypted message from the Golang code
const decryptedMessage = decrypt(encryptedMessage, key);
console.log(decryptedMessage);

此代码使用Golang中

pbkdf2
包中的
golang.org/x/crypto/pbkdf2
函数和Node.js中
pbkdf2Sync
模块中的
crypto
方法,使用PBKDF2算法从可变长度密钥中导出固定长度密钥以 SHA-256 作为哈希函数。然后使用派生密钥创建 AES 密码并像以前一样加密/解密消息。

© www.soinside.com 2019 - 2024. All rights reserved.