BouncyCastle产生一个PKCS#12规范的PFX/p12证书
RT,在C#中实现,依赖.netFramework2.0
BouncyCastle中提供了PKCS12Store,Pkcs12StoreBuilder,AsymmetricKeyEntry,X509CertificateEntry等接口
其中Pkcs12StoreBuilder建立一个PKCS12Store对象,PKCS12Store对象来产生一个pfx/p12格式的证书,该证书符合PKCS#12规范
PKCS#12的ref,见RSA给出的文档:PKCS #12: Personal Information Exchange Syntax Standard
PKCS12Store中方法load()和save(),加载和保存证书,其中的实现比较复杂,处理过程主要是对PKCS12证书内容的一组SafeBag进行判断和解包。一个PKCS12结构分析的文档:http://cid-780607117452312e.office.live.com/self.aspx/.Public/PKCS%5E3l2%E7%BB%93%E6%9E%84%E5%88%86%E6%9E%90.pdf
AsymmetricKeyEntry中封装了私钥,支持属性包的附加,attributeBag,可以方便获得私钥或封装私钥
类似的,X509CertificateEntry封装了公钥证书,支持属性包的附加和x509certificateV3的扩展,可以从中方便获得公钥等
这样,就可以通过产生一个pfx证书,保存CA的密钥对。这里pfx的certBag中证书采用的是x509certificateV1格式,因为没有用到v3格式证书的扩展
思路如下:
1、产生一对密钥对,其产生方法和保存方法之前有说过
产生密钥对:用Bouncy Castle的C#版API产生公钥和私钥
保存方法:在C#中保存Bouncy Castle生成的密钥对
2、配置自定义的x509Name对象,BouncyCastle中采用HashTable这种结构。
3、X509CertificateEntry封装公钥证书时,添加一个该公钥证书的alias。在测试过程(测试2)中,我导入该pfx证书到电脑的当前用户my证书存储区中,用微软的接口去读取时,用FriendlyName(就是该alias)来查找比较方便。另外(测试1),在store.Aliases这个属性去查找相匹配的alias,然后通过该alias从store中获取AsymmetricKeyEntry和X509CertificateEntry,从而获取私钥和公钥。
属性包FriendlyName,RSA的pkcs#9文档中提到过,不过不详细。链接:PKCS #9: Selected Attribute Types
另外,上面提到的属性包attributeBag和SafeBag,BouncyCastle中的PkcsObjectIdentifiers这个源代码中全部定义,可以参考下,其命名空间为:Org.BouncyCastle.Asn1.Pkcs.PkcsObjectIdentifiers(根据该命名空间的命名方式,可以在源代码中快速定位到该源文件)
生成的代码:
- char[] passwd = "123456".ToCharArray(); //pfx密码
- IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("RSA");
- RsaKeyGenerationParameters genPar = new RsaKeyGenerationParameters(
- BigInteger.ValueOf(0x10001), new SecureRandom(), 2048, 25);
- keyGen.Init(genPar);
- AsymmetricCipherKeyPair keypair = keyGen.GenerateKeyPair();
- RsaKeyParameters pubKey = (RsaKeyParameters)keypair.Public; //CA公钥
- RsaKeyParameters priKey = (RsaKeyParameters)keypair.Private; //CA私钥
- Hashtable attrs = new Hashtable();
- ArrayList order = new ArrayList();
- attrs.Add(X509Name.C, "CN"); //country code
- //attrs.Add(X509Name.ST, "Guangdong province"); //province name
- //attrs.Add(X509Name.L, "Guangzhou city"); //locality name
- attrs.Add(X509Name.O, "South China Normal University"); //organization
- attrs.Add(X509Name.OU, "South China Normal University"); //organizational unit name
- attrs.Add(X509Name.CN, "CAcert"); //common name
- attrs.Add(X509Name.E, "popozhude@qq.com");
- order.Add(X509Name.C);
- //order.Add(X509Name.ST);
- //order.Add(X509Name.L);
- order.Add(X509Name.O);
- order.Add(X509Name.OU);
- order.Add(X509Name.CN);
- order.Add(X509Name.E);
- X509Name issuerDN = new X509Name(order, attrs);
- X509Name subjectDN = issuerDN; //自签证书,两者一样
- X509V1CertificateGenerator v1certGen = new X509V1CertificateGenerator();
- v1certGen.SetSerialNumber(new BigInteger(128, new Random())); //128位
- v1certGen.SetIssuerDN(issuerDN);
- v1certGen.SetNotBefore(DateTime.UtcNow.AddDays(-1));
- v1certGen.SetNotAfter(DateTime.UtcNow.AddDays(365));
- v1certGen.SetSubjectDN(subjectDN);
- v1certGen.SetPublicKey(pubKey); //公钥
- v1certGen.SetSignatureAlgorithm("SHA1WithRSAEncryption");
- Org.BouncyCastle.X509.X509Certificate CAcert = v1certGen.Generate(priKey);
- CAcert.CheckValidity();
- CAcert.Verify(pubKey);
- //属性包
- /*
- Hashtable bagAttr = new Hashtable();
- bagAttr.Add(PkcsObjectIdentifiers.Pkcs9AtFriendlyName.Id,
- new DerBmpString("CA's Primary Certificate"));
- bagAttr.Add(PkcsObjectIdentifiers.Pkcs9AtLocalKeyID.Id,
- new SubjectKeyIdentifierStructure(pubKey));
- X509CertificateEntry certEntry = new X509CertificateEntry(CAcert,bagAttr);
- */
- X509CertificateEntry certEntry = new X509CertificateEntry(CAcert);
- Pkcs12Store store = new Pkcs12StoreBuilder().Build();
- store.SetCertificateEntry("CA's Primary Certificate", certEntry); //设置证书
- X509CertificateEntry[] chain = new X509CertificateEntry[1];
- chain[0] = certEntry;
- store.SetKeyEntry("CA's Primary Certificate", new AsymmetricKeyEntry(priKey), chain); //设置私钥
- FileStream fout = File.Create("CA.pfx");
- store.Save(fout, passwd, new SecureRandom()); //保存
- fout.Close();
测试1 ,把生成的pfx证书导入到计算机的证书store中,用微软提供的api去查找该证书。怎么通过MMC的证书管理单元对证书存储区进行管理:在MMC的证书管理单元中对证书存储区进行管理
- X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
- store.Open(OpenFlags.ReadOnly);
- X509Certificate2Collection storeCollection = (X509Certificate2Collection)store.Certificates;
- X509Certificate2 x509cert = null;
- foreach (X509Certificate2 cert in storeCollection)
- {
- //if(cert.Subject==" E = popozhude@qq.com, CN = CAcert, OU = South China Normal University, O = South China Normal University, C = CN")
- if (cert.FriendlyName == "CA's Primary Certificate")
- {
- x509cert = cert;
- //break;
- }
- }
- store.Close();
- if (x509cert == null)
- {
- Console.WriteLine("找不到指定的证书");
- }
- Console.WriteLine(x509cert.ToString());
- Console.ReadLine();
测试2 :读取本地的pfx证书,获取其公钥和私钥,这里主要用BouncyCastle的API,然后又把公钥证书转换成byte数组,再用微软的证书类api读取,成功。
- FileStream fs = File.OpenRead("CA.pfx"); //debug文件夹下的证书
- char[] passwd = "123456".ToCharArray();
- Pkcs12Store store = new Pkcs12StoreBuilder().Build();
- store.Load(fs, passwd); //加载证书
- string alias = null;
- foreach (string str in store.Aliases)
- {
- if (store.IsKeyEntry(str))
- alias = str;
- }
- if (alias == null)
- {
- Console.WriteLine("alias 为空");
- }
- else
- Console.WriteLine(alias);
- AsymmetricKeyEntry keyEntry = store.GetKey(alias);
- RsaKeyParameters priKey = (RsaKeyParameters)keyEntry.Key; //取得私钥
- X509CertificateEntry certEntry = store.GetCertificate(alias);
- Org.BouncyCastle.X509.X509Certificate x509cert = certEntry.Certificate;
- RsaKeyParameters pubKey = (RsaKeyParameters)x509cert.GetPublicKey(); //取得公钥
- x509cert.Verify(pubKey); //test ok
- byte[] certByte = x509cert.GetEncoded(); //把该证书转换成字节数组
- X509Certificate2 cert2 = new X509Certificate2(certByte); //微软的类X509Certificate2
- Console.WriteLine(cert2.ToString()); //显示正常,说明可以把BouncyCastle产生的数字v3证书,转换成X509Certificate2处理的证
- Console.Read();
BouncyCastle产生一个PKCS#12规范的PFX/p12证书的更多相关文章
- C#使用BouncyCastle生成PKCS#12数字证书
背景 生成数字证书用于PDF文档数字签名 数字证书需要考虑环境兼容性,如linux.windows 网上资料不全或版本多样 本文章主要介绍了在C#中使用BouncyCastle生成PKCS#12个人信 ...
- PKCS#12
http://blog.csdn.net/cuiran/article/details/7816696 数字证书介绍 一.什么是数字证书 数字证书就是互联网通讯中标志通讯各方身份信息的一系列数据,提供 ...
- .NET Core加解密实战系列之——使用BouncyCastle制作p12(.pfx)数字证书
简介 加解密现状,编写此系列文章的背景: 需要考虑系统环境兼容性问题(Linux.Windows) 语言互通问题(如C#.Java等)(加解密本质上没有语言之分,所以原则上不存在互通性问题) 网上资料 ...
- JKS和PKCS#12
今天来点实际工作中的硬通货! 与计费系统打交道,少不了用到加密/解密实现.为了安全起见,通过非对称加密交换对称加密密钥更是不可或缺.那么需要通过什么载体传递非对称算法公钥/私钥信息?数字证书是公钥的载 ...
- RSA私钥和公钥文件格式 (pkcs#1, pkcs#8, pkcs#12, pem)
RSA私钥和公钥文件格式 (pkcs#1, pkcs#8, pkcs#12, pem) 2018年03月07日 11:57:22 阅读数:674 Format Name Description PKC ...
- 一步一步实现一个Promise A+规范的 Promise
2015年6月,ES2015(即ES6)正式发布后受到了非常多的关注.其中很重要的一点是 Promise 被列为了正式规范. 在此之前很多库都对异步编程/回调地狱实现了类 Promise 的应对方案, ...
- java-信息安全(十七)-*.PFX(*.p12)&个人信息交换文件
原文地址 http://snowolf.iteye.com/blog/735294 与计费系统打交道,少不了用到加密/解密实现.为了安全起见,通过非对称加密交换对称加密密钥更是不可或缺.那么需要通过什 ...
- 【转载】OpenSSL 提取 pfx 数字证书公钥与私钥
转自https://www.cnblogs.com/Irving/p/9551110.html OpenSSL 提取 pfx 数字证书公钥与私钥 由于之前生产环境已经使用了 Identityser ...
- PKCS#1规范阅读笔记2--------公私钥ASN.1结构
PKCS#1种介绍了哈希算法的OID等的ASN.1结构,因为使用ASN.1的解码工具(比如:ASN1View)时,会自动显示出各OID的含义,所以这里就不说明了.下面就只简单摘抄一下RSA公私钥的AS ...
随机推荐
- dedecms内容页调用缩略图 缩略图多种用法(借鉴)
文章内容页调用缩略图方法如下两种.第一种没有大小设置.原图显示.第二种.可以设大小, (1) {dede:field.image/} (2)<img src="{dede:field. ...
- interproscan 的使用和遇到的问题
错误一: 2014-10-08 13:09:32,238 [uk.ac.ebi.interpro.scan.jms.worker.LocalJobQueueListener:193] ERROR - ...
- man page的介绍
假设你知道一个命令名,但不知其使用方法,此时可以求助于在线求助系统,即使用man(manual)命令,如man date. 上图为执行man date语句后的结果.<翻页查看时可按空格键,退出m ...
- Centos6下DRBD的安装配置
导读 Distributed Replicated Block Device(DRBD)是一个用软件实现的.无共享的.服务器之间镜像块设备内容的存储复制解决方案.数据镜像:实时.透明.同步(所有服务器 ...
- lecture7-序列模型及递归神经网络RNN(转载)
Hinton 第七课 .这里先说下RNN有recurrent neural network 和 recursive neural network两种,是不一样的,前者指的是一种人工神经网络,后者指的是 ...
- hdu4642 Fliping game ——博弈
link:http://acm.hdu.edu.cn/showproblem.php?pid=4642 refer to: http://www.cnblogs.com/jackge/archive/ ...
- C#部分---语言经典题目——兔子生兔子
根据本月成兔=上月成兔+上月小兔:本月小兔=上月幼兔:本月幼兔=本月成兔 利用while循环: Console.WriteLine("请输入月份:"); //int m = int ...
- Codeforces Round #149 (Div. 2)
A. Heads or Tails 枚举. B. Big Segment \(L=min(l_i),\ R=max(R_i)\) 判断是否存在区间\([L,R]\). C. King's Path 单 ...
- HDU 1061 Rightmost Digit --- 快速幂取模
HDU 1061 题目大意:给定数字n(1<=n<=1,000,000,000),求n^n%10的结果 解题思路:首先n可以很大,直接累积n^n再求模肯定是不可取的, 因为会超出数据范围, ...
- Oozie的安装过程
依赖CDH5,JDK和关系数据库 集群规划 主机名 IP Ooize节点 CHD1 XX.XX.XX.XX oozie server,oozie ...