如何在Golang中验证并恢复OpenSSL签名的文件?
在Golang中实现OpenSSL的
verifyrecover功能 你遇到的问题核心是:OpenSSL的pkeyutl -sign默认用的是不带哈希的PKCS#1 v1.5原始签名方案——本质是用私钥对原始数据执行PKCS#1 v1.5格式的"加密",而verifyrecover就是用公钥反向解密来恢复数据,同时验证签名有效性。
Golang的rsa.DecryptPKCS1v15虽然名字叫"解密",但完全可以用公钥完成这个操作(RSA算法中,私钥加密的内容可通过公钥解密),这正是你需要的验证+恢复功能。而rsa.VerifyPKCS1v15是用于验证带哈希的签名(比如先哈希数据,再签名哈希值),所以不适用你的场景。
具体实现步骤
- 加载PEM格式的公钥
- 读取签名文件
data.sig的内容 - 用公钥调用
rsa.DecryptPKCS1v15解密签名数据,得到原始内容(解密成功即代表签名有效)
完整代码示例
package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "fmt" "os" ) func main() { // 加载公钥 pubKeyData, err := os.ReadFile("pubkey.pem") if err != nil { fmt.Printf("读取公钥文件失败: %v\n", err) return } block, _ := pem.Decode(pubKeyData) if block == nil || block.Type != "PUBLIC KEY" { fmt.Println("解析公钥PEM失败") return } pubKey, err := x509.ParsePKIXPublicKey(block.Bytes) if err != nil { fmt.Printf("解析公钥失败: %v\n", err) return } rsaPubKey, ok := pubKey.(*rsa.PublicKey) if !ok { fmt.Println("公钥不是RSA类型") return } // 读取签名文件 sigData, err := os.ReadFile("data.sig") if err != nil { fmt.Printf("读取签名文件失败: %v\n", err) return } // 解密签名恢复原始数据(同时验证签名有效性) recoveredData, err := rsa.DecryptPKCS1v15(rand.Reader, rsaPubKey, sigData) if err != nil { fmt.Printf("签名验证失败/恢复数据出错: %v\n", err) return } // 输出恢复的数据 fmt.Println("恢复的原始数据:") fmt.Println(string(recoveredData)) // 可选:保存到文件 if err := os.WriteFile("recovered.txt", recoveredData, 0644); err != nil { fmt.Printf("保存恢复数据失败: %v\n", err) } }
关键说明
rsa.DecryptPKCS1v15第一个参数传rand.Reader即可,公钥解密不需要随机数(这个参数是为私钥解密时的填充随机数准备的,公钥场景下没用但必须传)- 如果签名无效(比如签名被篡改、用错公钥),解密会返回错误,这就是验证的逻辑
- 你的OpenSSL命令没有指定哈希算法,所以用的是原始签名方式,和代码逻辑完全匹配
内容的提问来源于stack exchange,提问作者T0maas
相关产品推荐
相关产品推荐

