Golang中如何解密RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING
Golang中如何解密RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING 我想在Go语言中使用RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING解密加密的长字符串。步骤如下:
-
对加密的长字符串进行base64解码,并将结果存储在el中 然后,我需要从el中提取密钥、公共数据、IV、加密的密钥和加密的数据
-
下一步是:使用IV、加密的密钥和私钥解密密钥
-
下一步是:使用加密的数据、IV和密钥解密数据,并将结果存储在解密后的文本中
-
最后,使用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/rsa、crypto/rand和crypto/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)
}
*/
注意:
parseEncryptedData函数需要根据你的实际数据格式进行调整- RSA私钥需要你实际提供,可以使用
x509.ParsePKCS1PrivateKey或x509.ParsePKCS8PrivateKey从PEM文件加载 - 如果使用不同的哈希函数或标签,需要调整
decryptRSAOAEP函数的参数 - 确保AES密钥长度正确(16, 24或32字节对应AES-128, AES-192, AES-256)
- 实际的数据格式可能需要根据你的加密方案进行调整

