在用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 则简单多了:
PrivateKeyInfo priInfo = PrivateKeyInfoFactory .CreatePrivateKeyInfo(password, enPrivateKeyInfo);
再导出私钥:
AsymmetricKeyParameter privateKey = 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;
- 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;
- using Org.BouncyCastle.Math;
- using Org.BouncyCastle.Asn1.X509;
- using Org.BouncyCastle.X509;
- using Org.BouncyCastle.Utilities.Collections;
- using Org.BouncyCastle.Asn1.Pkcs;
- using Org.BouncyCastle.Pkcs;
- using Org.BouncyCastle.Asn1;
-
- namespace ConsoleApplication1
- {
- class Program
- {
- static void Main(string[] args)
- {
-
- RsaKeyGeneratorTest();
-
- }
- private static void RsaKeyGeneratorTest()
- {
-
- RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();
-
- 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);
-
-
-
-
-
-
- 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));
- SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.GetInstance(aobject);
- AsymmetricKeyParameter testpublicKey = (RsaKeyParameters)PublicKeyFactory.CreateKey(pubInfo);
- FileStream fs;
- engine.Init(true, testpublicKey);
- try
- {
-
- 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));
- 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();
-
-
-
-
-
-
-
-
-
- string alg = "1.2.840.113549.1.12.1.3";
- 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();
-
-
-
- }
- }
- }
接下来就可以生成cer公钥证书或者pfx证书