You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

ASP.NET Core下基于BouncyCastle实现SHA1withRSA签名验签及生成CER/PEM密钥文件的技术咨询

Solution for SHA1withRSA Signing/Verification in ASP.NET Core + Key Conversion

Got it, let's tackle this step by step. I'll cover converting your existing RSA key text to CER/PEM files, plus complete examples for SHA1withRSA signing and verification using both BouncyCastle and native .NET Core APIs.


1. Converting RSA Key Text to CER (Public Key) and PEM (Private Key) Files

First, let's make sure your keys are in the right format for .NET and BouncyCastle:

Public Key to CER File

CER files use X.509 encoding for public keys. Here's how to handle different key formats from your generator:

  • If your public key starts with -----BEGIN PUBLIC KEY----- (PKCS#8 format):
    Simply copy the entire text (including the start/end markers) into a text editor, save it with a .cer extension (e.g., my_public_key.cer). This is already compatible with most tools.
  • If your public key starts with -----BEGIN RSA PUBLIC KEY----- (PKCS#1 format):
    You'll need to convert it to PKCS#8 first to save as a valid CER. Use this BouncyCastle snippet to do the conversion:
    using Org.BouncyCastle.Crypto.Parameters;
    using Org.BouncyCastle.OpenSsl;
    using Org.BouncyCastle.Security;
    using System.IO;
    using System.Text;
    
    public static byte[] ConvertPkcs1PublicKeyToPkcs8(string pkcs1PublicKeyText)
    {
        var reader = new PemReader(new StringReader(pkcs1PublicKeyText));
        var rsaParams = (RsaKeyParameters)reader.ReadObject();
        var subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(rsaParams);
        return subjectPublicKeyInfo.ToAsn1Object().GetDerEncoded();
    }
    
    // Usage:
    // string pkcs1Key = "-----BEGIN RSA PUBLIC KEY-----...-----END RSA PUBLIC KEY-----";
    // byte[] pkcs8Bytes = ConvertPkcs1PublicKeyToPkcs8(pkcs1Key);
    // File.WriteAllBytes("my_public_key.cer", pkcs8Bytes);
    

Private Key to PEM File

PEM format for private keys is straightforward:

  • If your private key starts with -----BEGIN RSA PRIVATE KEY----- (PKCS#1) or -----BEGIN PRIVATE KEY----- (PKCS#8):
    Copy the full text (including markers) into a text editor and save it with a .pem extension (e.g., my_private_key.pem).
  • If you have raw key text without markers:
    Wrap it in the appropriate headers. For PKCS#1 RSA private keys, use:
    -----BEGIN RSA PRIVATE KEY-----
    [your raw key text here]
    -----END RSA PRIVATE KEY-----
    

2. SHA1withRSA Signing/Verification Using BouncyCastle

First, install the BouncyCastle NuGet package:

Install-Package BouncyCastle.NetCore

Full Example Code

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Signers;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using System.IO;
using System.Text;

public class BouncyCastleSha1RsaHelper
{
    // Load private key from PEM file
    private static AsymmetricPrivateKeyParameter LoadPrivateKey(string pemPath)
    {
        using var reader = new PemReader(new StreamReader(pemPath));
        return (AsymmetricPrivateKeyParameter)reader.ReadObject();
    }

    // Load public key from CER file
    private static AsymmetricPublicKeyParameter LoadPublicKey(string cerPath)
    {
        byte[] cerBytes = File.ReadAllBytes(cerPath);
        var keyParams = PublicKeyFactory.CreateKey(cerBytes);
        return (AsymmetricPublicKeyParameter)keyParams;
    }

    // Sign data with SHA1withRSA
    public static byte[] Sign(string rawData, string privateKeyPath)
    {
        var privateKey = LoadPrivateKey(privateKeyPath);
        var signer = new RsaDigestSigner(new Org.BouncyCastle.Crypto.Digests.Sha1Digest());
        signer.Init(true, privateKey);
        
        byte[] dataBytes = Encoding.UTF8.GetBytes(rawData);
        signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
        
        return signer.GenerateSignature();
    }

    // Verify SHA1withRSA signature
    public static bool Verify(string rawData, byte[] signature, string publicKeyPath)
    {
        var publicKey = LoadPublicKey(publicKeyPath);
        var signer = new RsaDigestSigner(new Org.BouncyCastle.Crypto.Digests.Sha1Digest());
        signer.Init(false, publicKey);
        
        byte[] dataBytes = Encoding.UTF8.GetBytes(rawData);
        signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
        
        return signer.VerifySignature(signature);
    }

    // Test the workflow
    public static void RunTest()
    {
        string testData = "Hello, SHA1withRSA via BouncyCastle!";
        string privateKeyPath = "my_private_key.pem";
        string publicKeyPath = "my_public_key.cer";

        // Generate signature
        byte[] signature = Sign(testData, privateKeyPath);
        Console.WriteLine($"Signature (Base64): {Convert.ToBase64String(signature)}");

        // Verify signature
        bool isVerified = Verify(testData, signature, publicKeyPath);
        Console.WriteLine($"Verification Result: {isVerified}");
    }
}

3. Native .NET Core Implementation (No BouncyCastle)

You don't need external libraries for this—.NET Core has built-in APIs to handle SHA1withRSA (which uses RSA with PKCS#1 v1.5 padding and SHA1 hashing).

Full Example Code

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class NativeSha1RsaHelper
{
    // Load private key from PEM file
    private static RSA LoadPrivateKey(string pemPath)
    {
        string pemText = File.ReadAllText(pemPath)
                             .Replace("-----BEGIN RSA PRIVATE KEY-----", "")
                             .Replace("-----END RSA PRIVATE KEY-----", "")
                             .Replace("\r", "")
                             .Replace("\n", "");
        
        byte[] keyBytes = Convert.FromBase64String(pemText);
        RSA rsa = RSA.Create();
        rsa.ImportRSAPrivateKey(keyBytes, out _);
        return rsa;
    }

    // Load public key from CER file
    private static RSA LoadPublicKey(string cerPath)
    {
        byte[] cerBytes = File.ReadAllBytes(cerPath);
        RSA rsa = RSA.Create();
        rsa.ImportSubjectPublicKeyInfo(cerBytes, out _);
        return rsa;
    }

    // Sign data with SHA1withRSA
    public static byte[] Sign(string rawData, string privateKeyPath)
    {
        using var rsa = LoadPrivateKey(privateKeyPath);
        byte[] dataBytes = Encoding.UTF8.GetBytes(rawData);
        return rsa.SignData(dataBytes, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
    }

    // Verify SHA1withRSA signature
    public static bool Verify(string rawData, byte[] signature, string publicKeyPath)
    {
        using var rsa = LoadPublicKey(publicKeyPath);
        byte[] dataBytes = Encoding.UTF8.GetBytes(rawData);
        return rsa.VerifyData(dataBytes, signature, HashAlgorithmName.SHA1, RSASignaturePadding.Pkcs1);
    }

    // Test the workflow
    public static void RunTest()
    {
        string testData = "Hello, SHA1withRSA via native .NET!";
        string privateKeyPath = "my_private_key.pem";
        string publicKeyPath = "my_public_key.cer";

        // Generate signature
        byte[] signature = Sign(testData, privateKeyPath);
        Console.WriteLine($"Signature (Base64): {Convert.ToBase64String(signature)}");

        // Verify signature
        bool isVerified = Verify(testData, signature, publicKeyPath);
        Console.WriteLine($"Verification Result: {isVerified}");
    }
}

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

火山引擎 最新活动