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

如何在C#中实现符合NACH标准的PKCS#7文本文件签名?

C#/.NET 实现 NACH 要求的 PKCS#7 文本文件签名

.NET 对 NACH 签名算法的支持情况

NACH指定的签名算法是SHA256withRSA的PKCS#7(CMS)签名,这是标准密码学算法,.NET平台(包括.NET Framework、.NET Core/.NET 5+)完全支持,可通过两种方式实现:

  • .NET原生System.Security.Cryptography.Pkcs命名空间:封装了PKCS#7签名的完整流程,无需额外依赖
  • Bouncy Castle库:与Java实现逻辑高度一致,适合需要严格对齐Java代码细节的场景

对应Java步骤的C#实现

以下是与Java步骤一一对应的C#实现方案,包含两种实现方式:

方式1:.NET原生API实现

using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.Pkcs;
using System.Security.Cryptography.X509Certificates;

public class NachSignatureGenerator
{
    /// <summary>
    /// 生成符合NACH要求的PKCS#7签名
    /// </summary>
    /// <param name="pfxPath">PFX密钥库文件路径</param>
    /// <param name="pfxPassword">PFX文件密码</param>
    /// <param name="inputFilePath">待签名的文本文件路径</param>
    /// <returns>签名Base64、证书Base64、原始文件Base64</returns>
    public static (string SignatureBase64, string CertificateBase64, string OriginalFileBase64) GenerateSignature(string pfxPath, string pfxPassword, string inputFilePath)
    {
        // 步骤1:加载PFX密钥库,提取证书和私钥
        var cert = new X509Certificate2(
            pfxPath, 
            pfxPassword, 
            X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
        var privateKey = cert.GetRSAPrivateKey();

        // 步骤3:读取原始文件字节
        byte[] originalFileBytes = File.ReadAllBytes(inputFilePath);

        // 步骤2、4-8:创建PKCS#7签名(原生API已封装摘要+签名流程)
        var contentInfo = new ContentInfo(originalFileBytes);
        var signedCms = new SignedCms(contentInfo, false);
        var signer = new CmsSigner(cert)
        {
            DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1") // SHA256的OID,对应SHA256WITHRSA
        };
        signedCms.ComputeSignature(signer);
        byte[] signatureBytes = signedCms.Encode();

        // 步骤9:Base64编码签名
        string signatureBase64 = Convert.ToBase64String(signatureBytes);

        // 步骤10:Base64编码证书
        string certBase64 = Convert.ToBase64String(cert.RawData);

        // 步骤11:Base64编码原始文件
        string originalBase64 = Convert.ToBase64String(originalFileBytes);

        return (signatureBase64, certBase64, originalBase64);
    }
}

方式2:Bouncy Castle实现(与Java逻辑完全对齐)

先安装Bouncy Castle的NuGet包:

dotnet add package BouncyCastle.NetCore

实现代码:

using System;
using System.IO;
using Org.BouncyCastle.Cms;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;

public class NachBouncyCastleSignatureGenerator
{
    /// <summary>
    /// 用Bouncy Castle生成符合NACH要求的PKCS#7签名
    /// </summary>
    /// <param name="pfxPath">PFX密钥库文件路径</param>
    /// <param name="pfxPassword">PFX文件密码</param>
    /// <param name="inputFilePath">待签名的文本文件路径</param>
    /// <returns>签名Base64、证书Base64、原始文件Base64</returns>
    public static (string SignatureBase64, string CertificateBase64, string OriginalFileBase64) GenerateSignature(string pfxPath, string pfxPassword, string inputFilePath)
    {
        // 步骤1:加载PFX密钥库
        var pkcs12Store = new Pkcs12Store(
            new FileStream(pfxPath, FileMode.Open, FileAccess.Read), 
            pfxPassword.ToCharArray());
        
        // 获取密钥别名
        string alias = null;
        foreach (string al in pkcs12Store.Aliases)
        {
            if (pkcs12Store.IsKeyEntry(al))
            {
                alias = al;
                break;
            }
        }

        var keyEntry = pkcs12Store.GetKey(alias);
        var privateKey = keyEntry.Key;
        X509CertificateEntry certEntry = pkcs12Store.GetCertificate(alias);
        X509Certificate cert = certEntry.Certificate;

        // 步骤3:读取原始文件字节
        byte[] originalFileBytes = File.ReadAllBytes(inputFilePath);

        // 步骤4:创建CMSSignedDataGenerator(与Java代码一致)
        var generator = new CmsSignedDataGenerator();
        generator.AddSigner(
            privateKey, 
            cert, 
            CmsSignedDataGenerator.DigestSha256); // 对应SHA256WITHRSA算法

        // 生成PKCS#7签名
        var content = new CmsProcessableByteArray(originalFileBytes);
        CmsSignedData signedData = generator.Generate(content, false);
        byte[] signatureBytes = signedData.GetEncoded();

        // 步骤9:Base64编码签名
        string signatureBase64 = Convert.ToBase64String(signatureBytes);

        // 步骤10:Base64编码证书
        string certBase64 = Convert.ToBase64String(cert.GetEncoded());

        // 步骤11:Base64编码原始文件
        string originalBase64 = Convert.ToBase64String(originalFileBytes);

        return (signatureBase64, certBase64, originalBase64);
    }
}

注意事项

  • 加载PFX文件时,若遇到私钥访问权限问题,可调整X509KeyStorageFlags参数(比如添加X509KeyStorageFlags.UserKeySet)
  • 两种实现方式生成的签名均符合NACH的PKCS#7要求,可根据项目依赖选择合适的方案

内容的提问来源于stack exchange,提问作者Ashid Das

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 04:42:00