您的位置:首页 > 编程语言 > C#

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

2016-01-25 16:50 148 查看
用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证书
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: