亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang 中的 AES 256 CTR 加密 使用 CryptoJS 在 Node JS 中解密

Golang 中的 AES 256 CTR 加密 使用 CryptoJS 在 Node JS 中解密

Go
嚕嚕噠 2022-11-23 20:06:38
我必須使用 golang 將數據發送到具有 nodejs 加密的現有(遺留)服務,該服務將使用 AES CTR 模式和 Crypto JS libray 解密數據。我做了一些代碼如下(密鑰加密是這個問題中的隨機密鑰)。高朗加密:func main() {    rawKey := "46ca2a49c8074dadb99843f6b86c5975"    data := "the quick brown fox jumps over the lazy dog"        encryptedData := encrypt(rawKey, data);    fmt.Println("encrypted data: ", encryptedData)}func encrypt(rawKey string, data string) string {    key := []byte(rawKey)    plainText := []byte(data)    // Create new AES cipher block    block, err := aes.NewCipher(key)    if err != nil {        return err.Error()    }    // The IV (Initialization Vector) need to be unique, but not secure.    // Therefore, it's common to include it at the beginning of the cipher text.    cipherText := make([]byte, aes.BlockSize+len(plainText))    // Creates IV.    iv := cipherText[:aes.BlockSize]    if _, err := io.ReadFull(rand.Reader, iv); err != nil {        return err.Error()    }    // Encrypt.    encryptStream := cipher.NewCTR(block, iv)    encryptStream.XORKeyStream(cipherText[aes.BlockSize:], plainText)    ivHex := hex.EncodeToString(iv)    encryptedDataHex := hex.EncodeToString(cipherText)    return encryptedDataHex[0:len(ivHex)] + ":" + encryptedDataHex[len(ivHex):]}
查看完整描述

1 回答

?
慕俠2389804

TA貢獻1719條經驗 獲得超6個贊

代碼基本沒問題,只有幾個小問題:

  1. CryptoJS 不會自動禁用流密碼模式(如 CTR)的默認 PKCS7 填充。因此,必須在 Go 代碼中應用 PKCS7 填充。

  2. 由于CryptoJS代碼使用內部的PBKDF,所以解密需要OpenSSL格式(即Salted__的ASCII編碼后跟8字節salt和實際密文),十六進制編碼。因此 Go 代碼必須相應地格式化和編碼數據。

  3. CryptoJS在使用內部 PBKDF 時派生密鑰和 IV 。因此,在 CryptoJS 代碼中,指定的 IV在解密過程中被忽略。因此,在 Go 代碼中,可以指定任何IV。

以下代碼對應于您的代碼,由 PKCS#7 填充和結果的格式/編碼擴展(考慮代碼中的注釋)。請注意,與您的代碼一樣,為了簡單起見,使用了硬編碼鹽,但實際上出于安全原因,必須應用隨機生成的鹽:

package main


import (

    "crypto/aes"

    "crypto/cipher"

    "encoding/hex"

    "fmt"


    evp "github.com/walkert/go-evp"

    "github.com/zenazn/pkcs7pad"

)


func main() {

    rawKey := "46ca2a49c8074dadb99843f6b86c5975"

    data := pkcs7pad.Pad([]byte("the quick brown fox jumps over the lazy dog"), 16) // 1. Pad the plaintext with PKCS#7

    fmt.Println("padded data: ", hex.EncodeToString(data))


    encryptedData := encrypt(rawKey, data)

    fmt.Println("encrypted data: ", encryptedData)

}


func encrypt(rawKey string, plainText []byte) string {

    salt := []byte("ABCDEFGH") // hardcoded at the moment


    // Gets key and IV from raw key.

    key, iv := evp.BytesToKeyAES256CBCMD5([]byte(salt), []byte(rawKey))


    // Create new AES cipher block

    block, err := aes.NewCipher(key)

    if err != nil {

        return err.Error()

    }


    cipherText := make([]byte, len(plainText))


    // Encrypt.

    encryptStream := cipher.NewCTR(block, iv)

    encryptStream.XORKeyStream(cipherText, plainText)


    ivHex := hex.EncodeToString(iv)

    encryptedDataHex := hex.EncodeToString([]byte("Salted__")) + hex.EncodeToString(salt) + hex.EncodeToString(cipherText) // 2. Apply the OpenSSL format, hex encode the result

    return ivHex + ":" + encryptedDataHex // 3. Any value for ivHex can be used here, e.g. "00000000000000000000000000000000"

}

輸出是:


padded data:  74686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f670505050505

encrypted data:  3a010df5e7985f2d8b0c00e3a096347f:53616c7465645f5f41424344454647486036327f61cf3050fddd6ea76325148c81e170a63b514b8818afbbb894c874c87cc4c865300c7b2d0e0fd82826f3d3c5

可以使用遺留代碼解密此密文:


const decrypt = function (rawKey, encryptedData) {

    const split = encryptedData.split(':');

    if (split.length < 2) return '';


    const reb64 = CryptoJS.enc.Hex.parse(split[1]);

    const bytes = reb64.toString(CryptoJS.enc.Base64);

    

    const hash = CryptoJS.AES.decrypt(bytes, rawKey, {

        iv: split[0], // This is ignored if the internal PBKDF is used

        mode: CryptoJS.mode.CTR

    });

    const plain = hash.toString(CryptoJS.enc.Utf8);

    return plain;

}


const rawKey = '46ca2a49c8074dadb99843f6b86c5975';

const encryptedData = '3a010df5e7985f2d8b0c00e3a096347f:53616c7465645f5f41424344454647486036327f61cf3050fddd6ea76325148c81e170a63b514b8818afbbb894c874c87cc4c865300c7b2d0e0fd82826f3d3c5';


const decyptedData = decrypt(rawKey, encryptedData);

document.getElementById("pt").innerHTML = "decrypted data: " + decyptedData;

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

<p style="font-family:'Courier New', monospace;" id="pt"></p>


查看完整回答
反對 回復 2022-11-23
  • 1 回答
  • 0 關注
  • 566 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號