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加密的文档,需要注意以下几点:

  1. IV长度:GCM标准要求IV为12字节,但Node.js允许16字节IV,Go的cipher.NewGCM也支持非标准IV长度
  2. 认证标签:Node.js的setAuthTag对应GCM的认证标签,在Go中需要与密文分开处理
  3. 密钥处理: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');
回到顶部