javascript - AES CBC : JavaScript/CryptoJS Encrypt -> Golang Decrypt

标签 javascript go encryption aes cryptojs

注意:这仅供个人使用和学习,我不会尝试将自己的加密技术用于公共(public)用途。

我需要 AES256 加密一个字符串,但是我目前的尝试在十六进制解码时以 Salted__Vέ��|��l����ʼ8XCQlY 服务器端的字符串结束。十六进制解码后,它应该是一个有效的 utf8 base64 字符串,然后可以将其解码为原始字符串。这类似于提供的解决方案 here ,但是盐不是实际问题(尽管答案被接受)并且我无法通过在使用前对 iv 进行十六进制解码来抑制盐操作(如建议的那样)。有办法做到这一点吗?

我尝试了几种不同的方法,但总是以相似的方式结束。我最近的尝试是这样的:

加密.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 变量中:

解密.go

( golang decrypt playground )

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。请尝试使用 NewCB​​CDecrypter

关于javascript - AES CBC : JavaScript/CryptoJS Encrypt -> Golang Decrypt,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55308051/

相关文章:

javascript - CryptoJS 和 Pycrypto 协同工作

javascript - 等待 promise 链中的所有 promise

javascript - 为什么 req.body 不断返回空对象?

windows - 无法使用os.Chdir()更改目录

javascript - Python (django) 和 Javascript (crypto.js) 中的 PBKDF2 哈希值不一致

c# - CryptoStream 在关闭解密时抛出错误

javascript - 反转元素的顺序

javascript - Android 设备方向 compass

go - httptest 可以用来测试 HTTP/2 吗?

go - 如何使 golang 的 golang 版本和我的 Dockerfile 保持同步?