在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()方法。
测试代码:
- 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证书
在C#中保存Bouncy Castle生成的密钥对的更多相关文章
- 【Java密码学】使用Bouncy Castle生成数字签名、数字信封
Bouncy Castle(轻量级密码术包)是一种用于 Java 平台的开放源码的轻量级密码术包,它支持大量的密码术算法,并提供 JCE 1.2.1 的实现.最近项目上正好用到了Bouncy Cast ...
- Tensorflow中保存模型时生成的各种文件区别和作用
假如我们得到了如下的checkpoints, 上面的文件主要可以分成三类:一种是在保存模型时生成的文件,一种是我们在使用tensorboard时生成的文件,还有一种就是plugins这个文件夹,这个是 ...
- JAVA 解密pkcs7(smime.p7m)加密内容 ,公钥:.crt 私钥:.pem 使用Bouncy Castle生成数字签名、数字信封
第三方使用公钥.crt加密后返回的内容,需要使用私钥解密.pem 返回内容格式如下 MIME-Version: 1.0 Content-Disposition: attachment; filenam ...
- 用Bouncy Castle的C#版API产生公钥和私钥
开源API链接地址:The Legion of the Bouncy Castle Bouncy Castle,简称为BC,原本是java的一个开源JCE提供者,后来也提供了C#版本的API,我下载其 ...
- 加密 bouncy castle
1.去官方站点下载Bouncy Castle的JCE Provider包 bcprov-ext-jdk15-145.jar 2.把jar文件复制到 $JAVA_HOME$\jre\lib\ext 目录 ...
- Entity Framework入门教程(6)--- 在线场景中保存数据
在线场景中保存数据 在线场景中保存实体数据是一项相当容易的任务,因为使用的是同一个context,这个context会自动跟踪所有实体发生的更改. 下图说明了在线场景中的CUD(创建,更新,删除)操作 ...
- spark中saveAsTextFile如何最终生成一个文件
原文地址: http://www.cnblogs.com/029zz010buct/p/4685173.html 一般而言,saveAsTextFile会按照执行task的多少生成多少个文件,比如pa ...
- Android中保存静态秘钥实践(转)
本文我们将讲解一个Android产品研发中可能会碰到的一个问题:如何在App中保存静态秘钥以及保证其安全性.许多的移动app需要在app端保存一些静态字符串常量,其可能是静态秘钥.第三方appId等. ...
- EditPlus保存时不生成bak文件(转)
如何设置EditPlus保存时不生成bak文件 EditPlus是一个强大的编辑工具,不单单是编辑文字强大,很多的刚开始学习编程语言的初学者会选择它,例如html,js,php,java.小编刚开始学 ...
随机推荐
- C++ Primer : 第十一章 : 关联容器之关联容器的迭代器和操作
关联容器的操作 除了和顺序容器定义的类型之外,关联容器还定义了一下几种类型: 关联容器额外的类型别名 key_type 此容器类型的关键字类型 mapped_type 每个关键字关联的类型, ...
- codeforces 192e
link: http://codeforces.com/contest/330/problem/E /* ID: zypz4571 LANG: C++ TASK: 192e.cpp */ #inclu ...
- hilbert矩阵
希尔伯特矩阵 希尔伯特矩阵是一种数学变换矩阵 Hilbert matrix,矩阵的一种,其元素A(i,j)=1/(i+j-1),i,j分别为其行标和列标. 即: [1,1/2,1/3,……,1/n] ...
- UVa 839 天平
原题链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- Objective-c——UI基础开发第八天(QQ聊天界面)
一.知识点: QQ聊天界面 双模型的使用(dataModel和frameModel) UITextField的使用 通知的使用 拉伸图片的两种方法(slicing/image对象的resizeable ...
- Codeforces Round #119 (Div. 2)
A. Cut Ribbon \(f(i)\)表示长为\(i\)的布条最多可以剪几段. B. Counting Rhombi \(O(wh)\)枚举中心计算 C. Permutations 将序列一映射 ...
- 新浪代码部署手册 git管理工具
目前新浪云上的应用支持通过Git和SVN来部署代码. Git仓库地址 https://git.sinacloud.com/YOUR_APP_NAME SVN仓库地址 https://svn.sinac ...
- Hive不支持非相等的join
由于 hive 与传统关系型数据库面对的业务场景及底层技术架构都有着很大差异,因此,传统数据库领域的一些技能放到 Hive 中可能已不再适用.关于 hive 的优化与原理.应用的文章,前面也陆陆续续的 ...
- UVA-11468 Substring(AC自动机+DP)
题目大意:给一些模板串,一些字符的出现概率.问不会出现模板串的概率是多少. 题目分析:是比较简单的概率DP+AC自动机.利用全概率公式递推即可. 代码如下: # include<iostream ...
- hdu3342 拓扑序
题意:一个QQ群里面有一群大神,他们互相帮助解决问题,然后互相膜拜,于是有些人就称别人是他师父,现在给出很多师徒关系,问是否有矛盾 拓扑序,按师徒关系建边直接拓扑序就行了. #include<s ...