在C#中保存Bouncy Castle生成的密钥对 【自用笔记】

本文介绍如何使用 BouncyCastle 的 C# 版 API 生成 RSA 密钥对,并详细展示了公钥与私钥的保存方法,包括私钥的加密保存过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用Bouncy Castle的C#版API产生公钥和私钥中产生了一对密钥对,可以用bouncy caslte提供的API进行保存


公钥方面的3个类,具体代码根据命名空间自行查看其源代码:

Org.BouncyCastle.Asn1.X509.SubjectPublicKeyInfo

Org.BouncyCastle.X509.SubjectPublicKeyInfoFactory  

Org.BouncyCastle.Security.PublicKeyFactory

 

用法:

SubjectPublicKeyInfo subInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(rsaPublic);

//rsaPublic是产生的公钥,类型是AsymmetricKeyParameter/RsaKeyParameters,其中后者集成前者

AsymmetricKeyParameter testpublicKey = (RsaKeyParameters)PublicKeyFactory.CreateKey(subInfo);


私钥方面,但私钥保存到本地文件中时,可以选择加密保存,3DES with sha1,涉及到5个类:

Org.BouncyCastle.Asn1.Pkcs.PrivateKeyInfo

Org.BouncyCastle.Pkcs.PrivateKeyInfoFactory

Org.BouncyCastle.Security.PrivateKeyFactory


Org.BouncyCastle.Asn1.Pkcs.EncryptedPrivateKeyInfo

Org.BouncyCastle.Pkcs.EncryptedPrivateKeyInfoFactory


前面3个类的用法同上面公钥的类似

PrivateKeyInfo privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(rsaPrivate);

AsymmetricKeyParameter testResult = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(privInfo);


如果要加密保存私钥的话:

string alg = "1.2.840.113549.1.12.1.3"; // 3 key triple DES with SHA-1
byte[] salt = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int count=1000;
char[] password="123456".ToCharArray();
EncryptedPrivateKeyInfo enPrivateKeyInfo = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
    alg,
    password,
    salt,
    count,
    privateKey);


EncryptedPrivateKeyInfo恢复出PrivateKeyInfo则简单多了:

PrivateKeyInfopriInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password,enPrivateKeyInfo);

再导出私钥:

AsymmetricKeyParameterprivateKey = PrivateKeyFactory.CreateKey(priInfo);

 

SubjectPublicKeyInfo和PrivateKeyInfo都提供了ToAsn1Object()方法,转换成很Asn1Object,再使用GetEncoded()方法,生成byte数组,然后保存到本地。编码是BER,当然DER也是可以。从本地读取文件时逆过程即可,把读取到的byte数组转换成Asn1Object对象,再使用GetInstance()方法。

 

测试代码:


using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;    // X509Certificate2
using System.IO;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Crypto.Engines;  //IAsymmetricBlockCipher engine = new RsaEngine();
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Asn1.X509; //X509Name
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Utilities.Collections;   //X509V3CertificateGenerator
using Org.BouncyCastle.Asn1.Pkcs;   //PrivateKeyInfo
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Asn1;    
 
namespace ConsoleApplication1
{
    class Program
    { 
        static void Main(string[] args)
        {
            //公钥和密钥的生成,并加密解密测试
            RsaKeyGeneratorTest();    //done!!!!!
           
        }
        private static void RsaKeyGeneratorTest()
        {
            //RSA密钥对的构造器
            RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();
            //RSA密钥构造器的参数
            RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
                Org.BouncyCastle.Math.BigInteger.ValueOf(3),
                new Org.BouncyCastle.Security.SecureRandom(),
                1024,   //密钥长度
                25);
            //用参数初始化密钥构造器
            keyGenerator.Init(param);
            //产生密钥对
            AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
            //获取公钥和私钥
            AsymmetricKeyParameter publicKey = keyPair.Public;
            AsymmetricKeyParameter privateKey = keyPair.Private;
          
            if (((RsaKeyParameters)publicKey).Modulus.BitLength < 1024)
            {
                Console.WriteLine("failed key generation (1024) length test");
            }
            savetheKey(publicKey, privateKey);
            
            
            //一个测试……………………
            //输入,十六进制的字符串,解码为byte[]
            //string input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e";
            //byte[] testData = Org.BouncyCastle.Utilities.Encoders.Hex.Decode(input);           
            string input = "popozh RSA test";
            byte[] testData = Encoding.UTF8.GetBytes(input);
            //非对称加密算法,加解密用
            IAsymmetricBlockCipher engine = new RsaEngine();
            //公钥加密 
            //从保存在本地的磁盘文件中读取公钥
            Asn1Object aobject = Asn1Object.FromStream(new FileStream(@"E:/Desktop/a.pub",FileMode.Open,FileAccess.Read));  //a.puk??
            SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.GetInstance(aobject);
            AsymmetricKeyParameter testpublicKey = (RsaKeyParameters)PublicKeyFactory.CreateKey(pubInfo);
            FileStream fs;
            engine.Init(true, testpublicKey);
            try
            {
                //Console.WriteLine("加密前:" + Convert.ToBase64String(testData) + Environment.NewLine);
                testData = engine.ProcessBlock(testData, 0, testData.Length);
                Console.WriteLine("加密完成!" + Environment.NewLine);
                fs = new FileStream(@"E:/Desktop/encryptedBytes", FileMode.Create, FileAccess.Write);
                fs.Write(testData, 0, testData.Length);
                fs.Close();
                Console.WriteLine("保存密文成功" + Environment.NewLine);
            }
            catch (Exception ex)
            {
                Console.WriteLine("failed - exception " + Environment.NewLine + ex.ToString());
            }
            //私钥解密
            //获取加密的私钥,进行解密,获得私钥
            fs = new FileStream(@"E:/Desktop/encryptedBytes", FileMode.Open, FileAccess.Read);
            byte[] anothertestdata = new byte[1024];
            fs.Read(anothertestdata, 0, anothertestdata.Length);
            fs.Close();
            Asn1Object aobj = Asn1Object.FromStream(new FileStream(@"E:/Desktop/a.pri", FileMode.Open, FileAccess.Read));   //a.pvk??
            EncryptedPrivateKeyInfo enpri = EncryptedPrivateKeyInfo.GetInstance(aobj);
            char[] password = "123456".ToCharArray();
            PrivateKeyInfo priKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password, enpri);    //解密
            AsymmetricKeyParameter anotherprivateKey = PrivateKeyFactory.CreateKey(priKey);    //私钥
            engine.Init(false, anotherprivateKey);
            try
            {
                anothertestdata = engine.ProcessBlock(anothertestdata, 0, testData.Length);
                Console.WriteLine("解密后密文为:" + Encoding.UTF8.GetString(anothertestdata) + Environment.NewLine);
            }
            catch (Exception e)
            {
                Console.WriteLine("failed - exception " + e.ToString());
            }
            
            Console.Read();
           
        }
        private static void savetheKey(AsymmetricKeyParameter publicKey, AsymmetricKeyParameter privateKey)
        {
            //保存公钥到文件
            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
            Asn1Object aobject = publicKeyInfo.ToAsn1Object();
            byte[] pubInfoByte = aobject.GetEncoded();
            FileStream fs = new FileStream(@"E:/Desktop/a.pub", FileMode.Create, FileAccess.Write);
            fs.Write(pubInfoByte, 0, pubInfoByte.Length);
            fs.Close();
            //保存私钥到文件
            /*
            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
            aobject = privateKeyInfo.ToAsn1Object();
            byte[] priInfoByte = aobject.GetEncoded();
            fs = new FileStream(@"E:/Desktop/a.pri", FileMode.Create, FileAccess.Write);
            fs.Write(priInfoByte, 0, priInfoByte.Length);
            fs.Close();
            */
            string alg = "1.2.840.113549.1.12.1.3"; // 3 key triple DES with SHA-1
            byte[] salt = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
            int count=1000;
            char[] password="123456".ToCharArray();
            EncryptedPrivateKeyInfo enPrivateKeyInfo = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
                alg,
                password,
                salt,
                count,
                privateKey);
            byte[] priInfoByte = enPrivateKeyInfo.ToAsn1Object().GetEncoded();
            fs = new FileStream(@"E:/Desktop/a.pri", FileMode.Create, FileAccess.Write);
            fs.Write(priInfoByte, 0, priInfoByte.Length);
            fs.Close();
            //还原
            //PrivateKeyInfo priInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password, enPrivateKeyInfo);
            //AsymmetricKeyParameter privateKey = PrivateKeyFactory.CreateKey(priInfoByte);
         }
    }
}

接下来就可以生成cer公钥证书或者pfx证书

■Generation and parsing of PKCS#12 files. ■X.509: Generators and parsers for V1 and V3 certificates, V2 CRLs and attribute certificates. ■PBE algorithms supported by PBEUtil: PBEwithMD2andDES-CBC, PBEwithMD2andRC2-CBC, PBEwithMD5andDES-CBC, PBEwithMD5andRC2-CBC, PBEwithSHA1andDES-CBC, PBEwithSHA1andRC2-CBC, PBEwithSHA-1and128bitRC4, PBEwithSHA-1and40bitRC4, PBEwithSHA-1and3-keyDESEDE-CBC, PBEwithSHA-1and2-keyDESEDE-CBC, PBEwithSHA-1and128bitRC2-CBC, PBEwithSHA-1and40bitRC2-CBC, PBEwithHmacSHA-1, PBEwithHmacSHA-224, PBEwithHmacSHA-256, PBEwithHmacRIPEMD128, PBEwithHmacRIPEMD160, and PBEwithHmacRIPEMD256. ■Signature algorithms supported by SignerUtilities: MD2withRSA, MD4withRSA, MD5withRSA, RIPEMD128withRSA, RIPEMD160withRSA, RIPEMD256withRSA, SHA-1withRSA, SHA-224withRSA, SHA-256withRSAandMGF1, SHA-384withRSAandMGF1, SHA-512withRSAandMGF1, SHA-1withDSA, and SHA-1withECDSA. ■Symmetric key algorithms: AES, Blowfish, Camellia, CAST5, CAST6, DESede, DES, GOST28147, HC-128, HC-256, IDEA, NaccacheStern, RC2, RC4, RC5-32, RC5-64, RC6, Rijndael, Serpent, Skipjack, TEA/XTEA, Twofish, and VMPC. ■Symmetric key modes: CBC, CFB, CTS, GOFB, OFB, OpenPGPCFB, and SIC (or CTR). ■Symmetric key paddings: ISO10126d2, ISO7816d4, PKCS#5/7, TBC, X.923, and Zero Byte. ■Asymmetric key algorithms: RSA (with blinding), ElGamal, DSA, ECDSA. ■Asymmetric key paddings/encodings: ISO9796d1, OAEP, and PKCS#1. ■Digests: GOST3411, MD2, MD4, MD5, RIPEMD128, RIPEMD160, RIPEMD256, RIPEMD320, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, Tiger, and Whirlpool. ■Signer mechanisms: DSA, ECDSA, ECGOST3410, GOST3410, ISO9796d2, PSS, RSA. ■Key Agreement: Diffie-Hellman and EC-DH. ■Macs: CBCBlockCipher, CFBBlockCipher, GOST28147, HMac, and ISO9797 Alg. 3. ■PBE generators: PKCS#12, and PKCS#5 - schemes 1 and 2. ■OpenPGP (RFC 4880) ■Cryptographic Message Syntax (CMS, RFC 3852), including streaming API. ■Online Certificate Status Protocol (OCSP, RFC 2560). ■Time Stamp Protocol (TSP, RFC 3161). ■TLS/SSL Client with support for client side authentication.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值