簡體   English   中英

AES CBC:JavaScript / CryptoJS加密 - > Golang Decrypt

[英]AES CBC: JavaScript/CryptoJS Encrypt -> Golang Decrypt

注意:這僅供個人使用和學習,我不打算將自己的加密用於公共用途。

我需要AES256加密一個字符串, Salted__Vέ | l ʼ8XCQlY我的當前嘗試最終得到一個字符串,如Salted__Vέ | l ʼ8XCQlY服務器端,當它是十六進制解碼。 當十六進制解碼時,它應該是一個有效的utf8 base64字符串,然后可以將其解碼為原始字符串。 這與此處提供的解決方案類似,但鹽並不是實際問題(盡管答案被接受)並且我無法在使用前通過十六進制解碼iv來抑制鹽操作(如建議的那樣)。 有沒有辦法做到這一點?

我嘗試了幾種不同的方法,總是在類似的地方。 我的最新嘗試是這樣的:

encrypt.js

 // CryptoJS.pad.NoPadding={pad:function(){},unpad:function(){}}; const SECRET = '394812730425442A472D2F423F452848'; const iv = crypto.getRandomValues(new Uint8Array(16)); function enc(plainText) { var b64 = CryptoJS.AES.encrypt(plainText, SECRET, { iv, mode: CryptoJS.mode.CBC, // padding: CryptoJS.pad.NoPadding }).toString(); // Don't need? //var e64 = CryptoJS.enc.Base64.parse(b64); //var eHex = e64.toString(CryptoJS.enc.Hex); console.log("b64::", b64); return b64; } enc("SUPA_SECRET"); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script> 

現在我們取b64結果並將其粘貼到服務器端golang解密的JS_GEN變量中:

decrypt.go

golang解密操場

package main

import (
    "crypto/aes"
    "crypto/cipher"
    "encoding/base64"
    "encoding/hex"
    "fmt"
)

func main() {
    JS_GEN := "U2FsdGVkX1+CA3LZTXePlgoGqL8VkdgiDgUenZhH4kc="
    SECRET := "394812730425442A472D2F423F452848"
    //msg := "SUPER_SECRET"

    res, err := DecryptCBC(SECRET, JS_GEN)
    if err != nil {
        fmt.Println(err)
    }

    fmt.Println("res::", res)
}

func DecryptCBC(secret string, target string) (string, error) {
    nilString := ""
    key, _ := hex.DecodeString(secret)
    //ciphertext, err := base64.URLEncoding.DecodeString(target)

    // Decode base64 string
    ciphertext, err := base64.StdEncoding.DecodeString(target)
    if err != nil {
        return nilString, err
    }

    // Create new cipher block
    block, err := aes.NewCipher(key)
    if err != nil {
        return nilString, err
    }

    // The IV needs to be unique, but not secure. Therefore it's common to
    // include it at the beginning of the ciphertext.
    if len(ciphertext) < aes.BlockSize {
        panic("ciphertext too short")
    }
    iv := ciphertext[:aes.BlockSize]
    ciphertext = ciphertext[aes.BlockSize:]

    // CBC mode always works in whole blocks.
    if len(ciphertext)%aes.BlockSize != 0 {
        panic("ciphertext is not a multiple of the block size")
    }
    mode := cipher.NewCBCDecrypter(block, iv)

    // CryptBlocks can work in-place if the two arguments are the same.
    mode.CryptBlocks(ciphertext, ciphertext)
    fmt.Println("ciphertext::", ciphertext)

    // Output: exampleplaintext
    return string(ciphertext), nil
}

輸出將是這樣的:

ciphertext:: [136 227 244 124 124 92 162 254 1 147 235 213 8 136 129 150]
res:: ���||\�������

我究竟做錯了什么?

編輯:我從過程中刪除了十六進制編碼/解碼。

你似乎在JavaScript中使用CBC模式(默認),但在golang中使用CFB。 請嘗試使用NewCBCDecrypter

我還不完全確定以前的嘗試失敗的原因。 它可能是在服務器和客戶端上實現和/或配置加密的許多不同方式之一。

我終於找到了我想要的東西。 一個簡單的實現,只需開箱即用。 在這里,我們將使用crypto-jsgo-openssl

client.js

 const msg = "SUPA_SECRET" const key = "394812730425442A472D2F423F452848"; const encrypted = CryptoJS.AES.encrypt(msg, key); console.log(encrypted.toString()); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script> 

server.go

package main

import (
    "fmt"
    "github.com/Luzifer/go-openssl"
)

func main() {
    encrypted := "ENCRYPTED_STRING_HERE"
    secret := "394812730425442A472D2F423F452848"

    o := openssl.New()

    dec, err := o.DecryptBytes(secret, []byte(encrypted), openssl.DigestMD5Sum)
    if err != nil {
        fmt.Printf("An error occurred: %s\n", err)
    }

    fmt.Printf("Decrypted text: %s\n", string(dec))
}



// OUTPUT:
// Decrypted text: SUPA_SECRET

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM