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.cerextension (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.pemextension (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




