在C#中保存Bouncy Castle生成的密钥对

用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()方法。

 

测试代码:

 

 

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Collections;
  4 using System.Text;
  5 using System.Security.Cryptography;
  6 using System.Security.Cryptography.X509Certificates;    // X509Certificate2
  7 using System.IO;
  8 using Org.BouncyCastle.Crypto.Generators;
  9 using Org.BouncyCastle.Crypto.Parameters;
 10 using Org.BouncyCastle.Crypto;
 11 using Org.BouncyCastle.Security;
 12 using Org.BouncyCastle.Crypto.Engines;  //IAsymmetricBlockCipher engine = new RsaEngine();
 13 using Org.BouncyCastle.Math;
 14 using Org.BouncyCastle.Asn1.X509; //X509Name
 15 using Org.BouncyCastle.X509;
 16 using Org.BouncyCastle.Utilities.Collections;   //X509V3CertificateGenerator
 17 using Org.BouncyCastle.Asn1.Pkcs;   //PrivateKeyInfo
 18 using Org.BouncyCastle.Pkcs;
 19 using Org.BouncyCastle.Asn1;    
 20  
 21 namespace ConsoleApplication1
 22 {
 23     class Program
 24     { 
 25         static void Main(string[] args)
 26         {
 27             //公钥和密钥的生成,并加密解密测试
 28             RsaKeyGeneratorTest();    //done!!!!!
 29            
 30         }
 31         private static void RsaKeyGeneratorTest()
 32         {
 33             //RSA密钥对的构造器
 34             RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();
 35             //RSA密钥构造器的参数
 36             RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
 37                 Org.BouncyCastle.Math.BigInteger.ValueOf(3),
 38                 new Org.BouncyCastle.Security.SecureRandom(),
 39                 1024,   //密钥长度
 40                 25);
 41             //用参数初始化密钥构造器
 42             keyGenerator.Init(param);
 43             //产生密钥对
 44             AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
 45             //获取公钥和私钥
 46             AsymmetricKeyParameter publicKey = keyPair.Public;
 47             AsymmetricKeyParameter privateKey = keyPair.Private;
 48           
 49             if (((RsaKeyParameters)publicKey).Modulus.BitLength < 1024)
 50             {
 51                 Console.WriteLine("failed key generation (1024) length test");
 52             }
 53             savetheKey(publicKey, privateKey);
 54             
 55             
 56             //一个测试……………………
 57             //输入,十六进制的字符串,解码为byte[]
 58             //string input = "4e6f77206973207468652074696d6520666f7220616c6c20676f6f64206d656e";
 59             //byte[] testData = Org.BouncyCastle.Utilities.Encoders.Hex.Decode(input);           
 60             string input = "popozh RSA test";
 61             byte[] testData = Encoding.UTF8.GetBytes(input);
 62             //非对称加密算法,加解密用
 63             IAsymmetricBlockCipher engine = new RsaEngine();
 64             //公钥加密 
 65             //从保存在本地的磁盘文件中读取公钥
 66             Asn1Object aobject = Asn1Object.FromStream(new FileStream(@"E:/Desktop/a.pub",FileMode.Open,FileAccess.Read));  //a.puk??
 67             SubjectPublicKeyInfo pubInfo = SubjectPublicKeyInfo.GetInstance(aobject);
 68             AsymmetricKeyParameter testpublicKey = (RsaKeyParameters)PublicKeyFactory.CreateKey(pubInfo);
 69             FileStream fs;
 70             engine.Init(true, testpublicKey);
 71             try
 72             {
 73                 //Console.WriteLine("加密前:" + Convert.ToBase64String(testData) + Environment.NewLine);
 74                 testData = engine.ProcessBlock(testData, 0, testData.Length);
 75                 Console.WriteLine("加密完成!" + Environment.NewLine);
 76                 fs = new FileStream(@"E:/Desktop/encryptedBytes", FileMode.Create, FileAccess.Write);
 77                 fs.Write(testData, 0, testData.Length);
 78                 fs.Close();
 79                 Console.WriteLine("保存密文成功" + Environment.NewLine);
 80             }
 81             catch (Exception ex)
 82             {
 83                 Console.WriteLine("failed - exception " + Environment.NewLine + ex.ToString());
 84             }
 85             //私钥解密
 86             //获取加密的私钥,进行解密,获得私钥
 87             fs = new FileStream(@"E:/Desktop/encryptedBytes", FileMode.Open, FileAccess.Read);
 88             byte[] anothertestdata = new byte[1024];
 89             fs.Read(anothertestdata, 0, anothertestdata.Length);
 90             fs.Close();
 91             Asn1Object aobj = Asn1Object.FromStream(new FileStream(@"E:/Desktop/a.pri", FileMode.Open, FileAccess.Read));   //a.pvk??
 92             EncryptedPrivateKeyInfo enpri = EncryptedPrivateKeyInfo.GetInstance(aobj);
 93             char[] password = "123456".ToCharArray();
 94             PrivateKeyInfo priKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password, enpri);    //解密
 95             AsymmetricKeyParameter anotherprivateKey = PrivateKeyFactory.CreateKey(priKey);    //私钥
 96             engine.Init(false, anotherprivateKey);
 97             try
 98             {
 99                 anothertestdata = engine.ProcessBlock(anothertestdata, 0, testData.Length);
100                 Console.WriteLine("解密后密文为:" + Encoding.UTF8.GetString(anothertestdata) + Environment.NewLine);
101             }
102             catch (Exception e)
103             {
104                 Console.WriteLine("failed - exception " + e.ToString());
105             }
106             
107             Console.Read();
108            
109         }
110         private static void savetheKey(AsymmetricKeyParameter publicKey, AsymmetricKeyParameter privateKey)
111         {
112             //保存公钥到文件
113             SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
114             Asn1Object aobject = publicKeyInfo.ToAsn1Object();
115             byte[] pubInfoByte = aobject.GetEncoded();
116             FileStream fs = new FileStream(@"E:/Desktop/a.pub", FileMode.Create, FileAccess.Write);
117             fs.Write(pubInfoByte, 0, pubInfoByte.Length);
118             fs.Close();
119             //保存私钥到文件
120             /*
121             PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
122             aobject = privateKeyInfo.ToAsn1Object();
123             byte[] priInfoByte = aobject.GetEncoded();
124             fs = new FileStream(@"E:/Desktop/a.pri", FileMode.Create, FileAccess.Write);
125             fs.Write(priInfoByte, 0, priInfoByte.Length);
126             fs.Close();
127             */
128             string alg = "1.2.840.113549.1.12.1.3"// 3 key triple DES with SHA-1
129             byte[] salt = { 12345678910 };
130             int count=1000;
131             char[] password="123456".ToCharArray();
132             EncryptedPrivateKeyInfo enPrivateKeyInfo = EncryptedPrivateKeyInfoFactory.CreateEncryptedPrivateKeyInfo(
133                 alg,
134                 password,
135                 salt,
136                 count,
137                 privateKey);
138             byte[] priInfoByte = enPrivateKeyInfo.ToAsn1Object().GetEncoded();
139             fs = new FileStream(@"E:/Desktop/a.pri", FileMode.Create, FileAccess.Write);
140             fs.Write(priInfoByte, 0, priInfoByte.Length);
141             fs.Close();
142             //还原
143             //PrivateKeyInfo priInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(password, enPrivateKeyInfo);
144             //AsymmetricKeyParameter privateKey = PrivateKeyFactory.CreateKey(priInfoByte);
145          }
146     }
147 }

 

posted @ 2012-10-30 13:34  YaSin  阅读(3228)  评论(0编辑  收藏  举报