You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:26:14