在用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 = {
1,
2,
3,
4,
5,
6,
7,
8,
9,
10 };
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 }