Golang如何解密Node Js加密的文档
Golang如何解密Node Js加密的文档 使用相同的“Crypto”模块 aes-256-gcm、base64 编码,并且 IV = 16!! 解密在 Node.js 中加密的文档,其 IV=16 并使用了 setAuthTag。使用的密钥可以是任意 32 或 64 个字符长。在 Go 语言中,我使用 crypto/cipher 和 crypto/aes 来解密在 Node.js 中加密的文档。
3 回复
以下是用于解密文档的Go语言代码,假设您已拥有密文、密钥、初始化向量(IV)和认证标签:
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
)
func main() {
// 密文、密钥、IV和认证标签(base64编码字符串)
ciphertextB64 := "your_ciphertext_base64"
keyB64 := "your_key_base64"
ivB64 := "your_iv_base64"
authTagB64 := "your_auth_tag_base64"
// 解码base64字符串
ciphertext, _ := base64.StdEncoding.DecodeString(ciphertextB64)
key, _ := base64.StdEncoding.DecodeString(keyB64)
iv, _ := base64.StdEncoding.DecodeString(ivB64)
authTag, _ := base64.StdEncoding.DecodeString(authTagB64)
// 创建新的密码块
block, err := aes.NewCipher(key)
if err != nil {
// 处理错误
fmt.Println("Error creating cipher:", err)
return
}
// 创建GCM密码
aesgcm, err := cipher.NewGCM(block)
if err != nil {
// 处理错误
fmt.Println("Error creating GCM:", err)
return
}
// 解密密文
plaintext, err := aesgcm.Open(nil, iv, ciphertext, authTag)
if err != nil {
// 处理解密错误
fmt.Println("Decryption failed:", err)
return
}
// 打印解密后的明文
fmt.Println("Decrypted plaintext:", string(plaintext))
}
请记住:
- 将占位符替换为密文、密钥、IV和认证标签的实际base64编码值。
- 妥善处理潜在错误。
- 确保Node.js和Go语言加密实现之间的兼容性。
- 采用安全的密钥和IV处理实践。
更多关于Golang如何解密Node Js加密的文档的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
我找到了解决方案。
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"encoding/hex"
"fmt"
"strings"
)
const (
ivBytes = 16
algorithm = "aes-256-gcm"
secureKey = "<Your Secure Key>"
)
func main() {
doc := "<Your Encrypted String>"
decrypted, err := decrypt(doc)
if err != nil {
fmt.Println("Decryption error:", err)
return
}
fmt.Println("Encrypted text:", decrypted)
}
func decrypt(encrypted string) (string, error) {
// Split the encrypted string into ciphertext, IV, and authentication tag
data := strings.Split(encrypted, ".")
fmt.Println("Data[0]:", data[0])
fmt.Println("Data[1]:", data[1])
fmt.Println("Data[2]:", data[2])
if len(data) != 3 {
return "", fmt.Errorf("invalid encrypted string format")
}
// Decode base64 strings
ciphertext, err := base64.StdEncoding.DecodeString(data[0])
if err != nil {
return "", err
}
fmt.Println("CipherTextDecodeString:=", ciphertext)
iv, err := base64.StdEncoding.DecodeString(data[1])
if err != nil {
return "", err
}
fmt.Println("Length IV=", len(iv))
fmt.Println("IV values=", iv)
authTag, err := base64.StdEncoding.DecodeString(data[2])
if err != nil {
return "", err
}
fmt.Println("authTag values=", authTag)
//Use this to getAuthTag which is setAuthTag Method setting AuthTag in NodeJs
ciphertext = append(ciphertext, authTag...)
// Decode the secure key from hex
key, err := hex.DecodeString(secureKey)
if err != nil {
return "", err
}
fmt.Println("key values=", key)
// Create the AES cipher block using the decoded key
block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
fmt.Println("block values=", key)
aesgcm, err := cipher.NewGCMWithNonceSize(block, ivBytes)//using this when you have IV=16 size or you can use cipher.NewGCM() when IV=12 size
if err != nil {
return "", err
}
fmt.Println(aesgcm)
// Decrypt the ciphertext using the GCM mode
plaintext, err := aesgcm.Open(nil, iv, ciphertext, nil)
if err != nil {
return "", fmt.Errorf("decryption failed: %v", err)
}
return string(plaintext), nil
在Go中解密Node.js使用AES-256-GCM加密的文档,需要注意以下几点:
- IV长度:GCM标准要求IV为12字节,但Node.js允许16字节IV,Go的
cipher.NewGCM也支持非标准IV长度 - 认证标签:Node.js的
setAuthTag对应GCM的认证标签,在Go中需要与密文分开处理 - 密钥处理:32字符(32字节)对应AES-256,64字符需要解码为32字节
以下是完整的解密示例:
package main
import (
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"fmt"
"log"
)
func main() {
// 示例数据(实际应从加密文档获取)
encryptedData := "你的base64编码加密数据"
authTag := "你的base64编码认证标签"
key := "32字节长度的密钥字符串"
iv := "16字节长度的IV字符串"
// 解码base64数据
ciphertext, err := base64.StdEncoding.DecodeString(encryptedData)
if err != nil {
log.Fatal("密文解码失败:", err)
}
tag, err := base64.StdEncoding.DecodeString(authTag)
if err != nil {
log.Fatal("认证标签解码失败:", err)
}
// 处理密钥(32字符直接使用,64字符需要解码)
var keyBytes []byte
if len(key) == 64 {
// 如果是64字符hex字符串
keyBytes, err = hex.DecodeString(key)
if err != nil {
log.Fatal("密钥解码失败:", err)
}
} else {
keyBytes = []byte(key)
}
ivBytes := []byte(iv)
// 解密
plaintext, err := decryptGCM(keyBytes, ciphertext, ivBytes, tag)
if err != nil {
log.Fatal("解密失败:", err)
}
fmt.Printf("解密结果: %s\n", plaintext)
}
func decryptGCM(key, ciphertext, iv, tag []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// 创建GCM模式,支持非标准IV长度
gcm, err := cipher.NewGCMWithNonceSize(block, len(iv))
if err != nil {
return nil, err
}
// 合并密文和认证标签(GCM期望的格式)
sealedData := append(ciphertext, tag...)
// 解密
return gcm.Open(nil, iv, sealedData, nil)
}
如果Node.js加密时使用了额外的关联数据(AAD),需要在解密时提供:
func decryptGCMWithAAD(key, ciphertext, iv, tag, aad []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCMWithNonceSize(block, len(iv))
if err != nil {
return nil, err
}
sealedData := append(ciphertext, tag...)
return gcm.Open(nil, iv, sealedData, aad)
}
关键注意事项:
- Node.js的
getAuthTag()返回的认证标签需要单独传递 - 如果密钥是64字符hex字符串,需要先解码为32字节
cipher.NewGCMWithNonceSize允许使用16字节IV- 认证标签必须附加在密文之后传递给
Open()方法
确保Node.js加密代码类似这样:
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
cipher.setAAD(aad); // 如果有AAD
let encrypted = cipher.update(data, 'utf8', 'base64');
encrypted += cipher.final('base64');
const authTag = cipher.getAuthTag().toString('base64');

