Golang中如何解密RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING

Golang中如何解密RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING 我想在Go语言中使用RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING解密加密的长字符串。步骤如下:

  1. 对加密的长字符串进行base64解码,并将结果存储在el中 然后,我需要从el中提取密钥、公共数据、IV、加密的密钥和加密的数据

  2. 下一步是:使用IV、加密的密钥和私钥解密密钥

  3. 下一步是:使用加密的数据、IV和密钥解密数据,并将结果存储在解密后的文本中

  4. 最后,使用HMAC大小32和UTF-8验证解密后的文本,以获取明文数据

如果能用Go语言实现上述步骤,我将不胜感激。提前感谢。


更多关于Golang中如何解密RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中如何解密RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中实现RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING解密需要结合标准库的crypto/rsacrypto/randcrypto/sha256等包。以下是完整的实现示例:

package main

import (
    "crypto/rsa"
    "crypto/rand"
    "crypto/sha256"
    "crypto/aes"
    "crypto/cipher"
    "crypto/hmac"
    "encoding/base64"
    "encoding/binary"
    "errors"
    "fmt"
    "hash"
)

func decryptRSAOAEP(ciphertext []byte, privKey *rsa.PrivateKey) ([]byte, error) {
    // 使用SHA-256作为哈希函数,MGF1使用SHA-256
    hash := sha256.New()
    label := []byte("")
    
    // RSA-OAEP解密
    plaintext, err := rsa.DecryptOAEP(hash, rand.Reader, privKey, ciphertext, label)
    if err != nil {
        return nil, fmt.Errorf("RSA解密失败: %v", err)
    }
    return plaintext, nil
}

func decryptAESCBC(ciphertext, key, iv []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    
    if len(ciphertext) < aes.BlockSize {
        return nil, errors.New("密文太短")
    }
    
    // CBC模式解密
    mode := cipher.NewCBCDecrypter(block, iv)
    plaintext := make([]byte, len(ciphertext))
    mode.CryptBlocks(plaintext, ciphertext)
    
    // 移除PKCS#7填充
    padding := int(plaintext[len(plaintext)-1])
    if padding < 1 || padding > aes.BlockSize {
        return nil, errors.New("填充无效")
    }
    return plaintext[:len(plaintext)-padding], nil
}

func verifyHMAC(data, key []byte, hashFunc func() hash.Hash) (bool, error) {
    if len(data) < 32 {
        return false, errors.New("数据长度不足")
    }
    
    // 分离数据和HMAC
    message := data[:len(data)-32]
    receivedHMAC := data[len(data)-32:]
    
    // 计算HMAC
    h := hmac.New(hashFunc, key)
    h.Write(message)
    expectedHMAC := h.Sum(nil)
    
    return hmac.Equal(receivedHMAC, expectedHMAC), nil
}

func parseEncryptedData(el []byte) ([]byte, []byte, []byte, []byte, []byte, error) {
    // 假设数据格式为: [密钥长度(4字节)][公钥数据][IV(16字节)][加密密钥][加密数据]
    if len(el) < 4 {
        return nil, nil, nil, nil, nil, errors.New("数据格式无效")
    }
    
    // 读取密钥长度
    keyLen := binary.BigEndian.Uint32(el[:4])
    offset := 4
    
    // 提取公钥数据
    if offset+int(keyLen) > len(el) {
        return nil, nil, nil, nil, nil, errors.New("公钥数据长度无效")
    }
    publicData := el[offset : offset+int(keyLen)]
    offset += int(keyLen)
    
    // 提取IV (16字节)
    if offset+16 > len(el) {
        return nil, nil, nil, nil, nil, errors.New("IV长度无效")
    }
    iv := el[offset : offset+16]
    offset += 16
    
    // 提取加密的密钥 (RSA密钥大小,例如256字节对应2048位RSA)
    rsaKeySize := 256 // 根据实际情况调整
    if offset+rsaKeySize > len(el) {
        return nil, nil, nil, nil, nil, errors.New("加密密钥长度无效")
    }
    encryptedKey := el[offset : offset+rsaKeySize]
    offset += rsaKeySize
    
    // 剩余的是加密数据
    encryptedData := el[offset:]
    
    return publicData, iv, encryptedKey, encryptedData, nil, nil
}

func main() {
    // 示例:假设这是你的base64编码的加密字符串
    base64Encoded := "YOUR_BASE64_ENCODED_STRING_HERE"
    
    // 1. Base64解码
    el, err := base64.StdEncoding.DecodeString(base64Encoded)
    if err != nil {
        panic(fmt.Sprintf("Base64解码失败: %v", err))
    }
    
    // 2. 解析加密数据
    publicData, iv, encryptedKey, encryptedData, _, err := parseEncryptedData(el)
    if err != nil {
        panic(fmt.Sprintf("解析加密数据失败: %v", err))
    }
    
    // 3. 加载RSA私钥 (这里需要你实际的私钥)
    // 假设你有一个PEM格式的私钥
    // privKey, err := loadPrivateKeyFromPEM("private.pem")
    // 这里使用示例私钥结构
    var privKey *rsa.PrivateKey // 需要你实际初始化这个私钥
    
    // 4. 解密RSA加密的密钥
    decryptedKey, err := decryptRSAOAEP(encryptedKey, privKey)
    if err != nil {
        panic(fmt.Sprintf("RSA解密密钥失败: %v", err))
    }
    
    // 5. 使用AES-CBC解密数据
    decryptedText, err := decryptAESCBC(encryptedData, decryptedKey, iv)
    if err != nil {
        panic(fmt.Sprintf("AES解密数据失败: %v", err))
    }
    
    // 6. 验证HMAC
    // 假设HMAC密钥是解密后的密钥的一部分或单独提供
    hmacKey := decryptedKey // 或者使用特定的HMAC密钥
    
    valid, err := verifyHMAC(decryptedText, hmacKey, sha256.New)
    if err != nil {
        panic(fmt.Sprintf("HMAC验证失败: %v", err))
    }
    
    if !valid {
        panic("HMAC验证不通过")
    }
    
    // 7. 提取明文数据 (移除HMAC)
    plaintext := decryptedText[:len(decryptedText)-32]
    
    fmt.Printf("解密成功: %s\n", string(plaintext))
}

// 辅助函数:从PEM文件加载私钥
/*
func loadPrivateKeyFromPEM(filename string) (*rsa.PrivateKey, error) {
    pemData, err := os.ReadFile(filename)
    if err != nil {
        return nil, err
    }
    
    block, _ := pem.Decode(pemData)
    if block == nil {
        return nil, errors.New("无法解码PEM块")
    }
    
    return x509.ParsePKCS1PrivateKey(block.Bytes)
}
*/

注意:

  1. parseEncryptedData函数需要根据你的实际数据格式进行调整
  2. RSA私钥需要你实际提供,可以使用x509.ParsePKCS1PrivateKeyx509.ParsePKCS8PrivateKey从PEM文件加载
  3. 如果使用不同的哈希函数或标签,需要调整decryptRSAOAEP函数的参数
  4. 确保AES密钥长度正确(16, 24或32字节对应AES-128, AES-192, AES-256)
  5. 实际的数据格式可能需要根据你的加密方案进行调整
回到顶部