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

C#中SHA256加密+私钥签名+Base64转换问题求助

签名生成问题排查

问题描述

需实现的加密签名流程:

  • 使用SHA256算法加密普通字符串
  • 用自有私钥对加密后的文本进行签名
  • 将结果字节数组转为Base64字符串作为API请求头传递

现有代码无法生成正确签名串,传入原始数据为message,验证结果不正确:

byte[] signedBytes, originalData;
string temp_inBase64;
using (SHA256 hash = SHA256Managed.Create())
{
Encoding enc = Encoding.UTF8;
originalData = hash.ComputeHash(enc.GetBytes(message));
}
using (var rsa = new RSACryptoServiceProvider())
{
rsa.FromXmlString("xxxxxx"); //Final
try
{
signedBytes = rsa.SignData(originalData, new SHA256CryptoServiceProvider());
temp_inBase64 = Convert.ToBase64String(signedBytes);
}
catch (CryptographicException e)
{
Console.WriteLine(e.Message);
return null;
}
finally
{
rsa.PersistKeyInCsp = false;
}
}
return temp_inBase64;

排查与修复方案

1. 核心错误:重复哈希

你的代码存在关键逻辑错误:先手动对原始字符串做了SHA256哈希,随后调用SignData方法时,该方法会再次对输入的哈希值执行SHA256哈希,相当于对原始数据做了两次SHA256哈希后再签名,完全不符合预期流程。

修复方案二选一:

方案A:用SignData直接处理原始字符串(推荐)

移除手动哈希步骤,让SignData内部自动完成哈希操作:

byte[] signedBytes;
string temp_inBase64;
Encoding enc = Encoding.UTF8;
byte[] originalData = enc.GetBytes(message);

using (var rsa = new RSACryptoServiceProvider())
{
    rsa.FromXmlString("xxxxxx");
    try
    {
        // SignData会自动对原始字节数据做SHA256哈希后签名
        signedBytes = rsa.SignData(originalData, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
        temp_inBase64 = Convert.ToBase64String(signedBytes);
    }
    catch (CryptographicException e)
    {
        Console.WriteLine(e.Message);
        return null;
    }
    finally
    {
        rsa.PersistKeyInCsp = false;
    }
}
return temp_inBase64;

方案B:手动哈希后用SignHash签名

若必须先手动执行SHA256哈希,需改用SignHash方法直接对哈希值签名:

byte[] signedBytes, hashBytes;
string temp_inBase64;
Encoding enc = Encoding.UTF8;

using (SHA256 hash = SHA256.Create())
{
    hashBytes = hash.ComputeHash(enc.GetBytes(message));
}

using (var rsa = new RSACryptoServiceProvider())
{
    rsa.FromXmlString("xxxxxx");
    try
    {
        // 直接对已哈希的值签名,避免重复哈希
        signedBytes = rsa.SignHash(hashBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
        temp_inBase64 = Convert.ToBase64String(signedBytes);
    }
    catch (CryptographicException e)
    {
        Console.WriteLine(e.Message);
        return null;
    }
    finally
    {
        rsa.PersistKeyInCsp = false;
    }
}
return temp_inBase64;

2. 其他需验证的点

  • 私钥合法性:确认rsa.FromXmlString传入的XML私钥是完整的合法RSA私钥,包含<RSAKeyValue>节点。
  • 编码一致性:确保API验证方同样使用UTF-8编码处理原始字符串,和你的代码保持一致。
  • 签名填充方式:默认RSACryptoServiceProvider使用PKCS#1填充,需确认验证方使用相同的填充规则,否则会验证失败。

内容的提问来源于stack exchange,提问作者transport company

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 11:31:05