【证书】PFX证书、CER证书申请流程详解
我们一般说的证书就是数字证书:数字证书是指在互联网通讯中标志通讯各方身份信息的一个数字认证,人们可以在网上用它来识别对方的身份
一般有两种:PFX证书、CER证书
(资料图片仅供参考)
PFX证书: 由Public Key Cryptography Standards #12,PKCS#12标准定义,包含了公钥和私钥的二进制格式的证书形式,以pfx作为证书文件后缀名。
一般RSA证书比较多,现在国内的RSA根证到期,有些企业已经不用了。
SM2证书: 1.二进制编码的证书 证书中没有私钥,DER 编码二进制格式的证书文件,以cer作为证书文件后缀名。 2.Base64编码的证书 证书中没有私钥,BASE64 编码格式的证书文件,也是以cer作为证书文件后缀名。
一般简称SM2证书也为cer证书
下面就着重讲一下SM2证书 申请流程:一般个人/企业在设备上生成csr文件,包含身份信息一起提交给CA,CA会给你制作一本证书,这证书具有一定的法律效应的哦。
证书信息一般CA返回的是证书base64编码形式,直接把保存到记事本以.cer结尾,双击就可以看到证书的相关信息
下面是证书的示例: 是不是可以看到证书的相关信息。
我们可以用证书来进行签名验签,加解密等操作;我们还会提取证书的相关信息。
下面重点来了,我们讲一下怎么获取到证书的相关信息,这才是本文的重中之重
解析证书我们离不开一个依赖包,就是bc包,这个bc包很重要
org.bouncycastlebcprov-jdk15on1.64
这个bc包里面的一些方法,如:Certificate 就是专门用来为证书服务的,在证书行业以及工程中必不可少
步骤
将证书base64编码转换为byte类型
byte[] buffer = Base64.decodeBase64(certBase64);
2.将byte转换为普通stream型
ByteArrayInputStream bIn = new ByteArrayInputStream(buffer);
3.将普通stream转为证书服务所需特定的stream型
ASN1InputStream dIn = new ASN1InputStream(bIn);ASN1Sequence asq = (ASN1Sequence) dIn.readObject();
4.转证书
Certificate certificate = Certificate.getInstance(asq);
5.解析证书内容
// 系列号解析 String serialNo = certificate.getSerialNumber().getValue().toString(16); System.out.println("序列号:" + serialNo);
解析签名算法,一般证书实际的签名算法是字符串,但是解析出来的是特定形式,这个特定形式国际上就是用来代表某种算法,所以要特别注意下
// 签名算法 1.2.156.10197.1.501 表示SM2算法 String algorithm = certificate.getSignatureAlgorithm().getAlgorithm().toString(); System.out.println("算法:" + algorithm);
// 颁发者 String issuer = certificate.getIssuer().toString(); System.out.println("颁发者:" + issuer);
解析出来的时间是date类型的,如果你不想要date类型而是获取string类型,一定要注意:你获取到的是GMT格式的字符串,这个字符串和实际的背景时间相差8小时,所以还是老老实实按照的方法获取date再进行格式转换
DateUtils.getDateString是我自己写的时间转换工具类。下一篇中我再贴出来。
Date startTime = certificate.getStartDate().getDate(); String startTimeStr = DateUtils.getDateString(startTime, "yyyy-MM-dd HH:mm:ss"); System.out.println("有效期:" + startTimeStr);
Date endTime = certificate.getEndDate().getDate(); String endTimeStr = DateUtils.getDateString(endTime, "yyyy-MM-dd HH:mm:ss"); System.out.println("失效日:" + endTimeStr);
这是获取使用者中CN项,如果你不想要CN而是想要获取整个使用者,可以直接到certificate.getSubject()为止
org.bouncycastle.asn1.x500.RDN rdn = certificate.getSubject().getRDNs(BCStyle.CN)[0]; String cn = rdn.getFirst().getValue().toString(); System.out.println("CN:" + cn);
这是解析公钥,一般比较重要,每家CA的公钥格式可能不一样,所以获取到的结果有细微差别,就是前缀是否带有:04标识
DERBitString publicKeyData = certificate.getSubjectPublicKeyInfo().getPublicKeyData(); String publicKeyDataStr = publicKeyData.toString().replaceAll("#034200", ""); System.out.println("公钥:" + publicKeyDataStr);
附加解析:现在主流的CA都会有家扩展项,就是oid,我们有时候也需要解析下oid的值,oid的解析一般用循环解析方式。
Extensions exes= certificate.getTBSCertificate().getExtensions(); ASN1ObjectIdentifier[] list = exes.getExtensionOIDs(); for (ASN1ObjectIdentifier a:list) {Extension el = exes.getExtension(a); String oid = el.getExtnId().toString(); String value = new String(el.getExtnValue().getOctets()); System.out.println("oid:" + oid + "->" + "value:" + value); }
特别说明:扩展项中我们这是解析出所有扩展项,有些扩展项的value是乱码,目前还不知道每家CA这些扩展项到底是啥编码格式。我试过了主流的编码格式,都不行,都是乱码,只有纯字符串的才正常。
来看下实际效果:
由于证书是比较重要的东西,一般不随便泄露,所以重要信息已经打码,悉知。
一般用到的扩展项有两种:个人扩展项,企业扩展项,这两种都有国际标准个人身份标识码 IdentifyCode oid固定为:1.2.156.10260.4.1.1 企业组织机构代码 oid固定为:1.2.156. 10260.4.1.4
这是亲手实践出来的, 目前在各网站还未知道详细的解析方式。尊重原创,谢谢!!
最后附上全部源码
package jp.utils;import org.apache.commons.codec.binary.Base64;import org.bouncycastle.asn1.ASN1InputStream;import org.bouncycastle.asn1.ASN1ObjectIdentifier;import org.bouncycastle.asn1.ASN1Sequence;import org.bouncycastle.asn1.DERBitString;import org.bouncycastle.asn1.x500.style.BCStyle;import org.bouncycastle.asn1.x509.Certificate;import org.bouncycastle.asn1.x509.Extension;import org.bouncycastle.asn1.x509.Extensions;import java.io.ByteArrayInputStream;import java.util.Date;public class DecodeCertUtils {public static void main(String[] args) {String certBase64 = ""; try {byte[] buffer = Base64.decodeBase64(certBase64); ByteArrayInputStream bIn = new ByteArrayInputStream(buffer); ASN1InputStream dIn = new ASN1InputStream(bIn); ASN1Sequence asq = (ASN1Sequence) dIn.readObject(); Certificate certificate = Certificate.getInstance(asq); Extensions exes= certificate.getTBSCertificate().getExtensions(); ASN1ObjectIdentifier[] list = exes.getExtensionOIDs(); for (ASN1ObjectIdentifier a:list) {Extension el = exes.getExtension(a); String oid = el.getExtnId().toString(); String value = new String(el.getExtnValue().getOctets()); System.out.println("oid:" + oid + "->" + "value:" + value); }// 系列号解析 String serialNo = certificate.getSerialNumber().getValue().toString(16); System.out.println("序列号:" + serialNo); // 签名算法 1.2.156.10197.1.501 表示SM2算法 String algorithm = certificate.getSignatureAlgorithm().getAlgorithm().toString(); System.out.println("算法:" + algorithm); // 颁发者 String issuer = certificate.getIssuer().toString(); System.out.println("颁发者:" + issuer); Date startTime = certificate.getStartDate().getDate(); String startTimeStr = DateUtils.getDateString(startTime, "yyyy-MM-dd HH:mm:ss"); System.out.println("有效期:" + startTimeStr); Date endTime = certificate.getEndDate().getDate(); String endTimeStr = DateUtils.getDateString(endTime, "yyyy-MM-dd HH:mm:ss"); System.out.println("失效日:" + endTimeStr); org.bouncycastle.asn1.x500.RDN rdn = certificate.getSubject().getRDNs(BCStyle.CN)[0]; String cn = rdn.getFirst().getValue().toString(); System.out.println("CN:" + cn); DERBitString publicKeyData = certificate.getSubjectPublicKeyInfo().getPublicKeyData(); String publicKeyDataStr = publicKeyData.toString().replaceAll("#034200", ""); System.out.println("公钥:" + publicKeyDataStr); bIn.close(); dIn.close(); } catch (Exception e) {e.printStackTrace(); } }}
标签:
相关推荐:
最新新闻:
- 如何将图像数据编码为比特流?转换方法步骤
- PF的关键字顺序有多灵活?PF防火墙最详细教程
- 华为t2010怎么刷机?华为t2010刷机教程及评测_全球今日报
- windows7桌面图标怎么改大小?修改方法步骤
- iphone4s怎么设置彩信?iphone4s联通卡彩信设置方法
- 什么软件修图较好?图片处理有哪些技巧?
- 国内常用的ntp服务器 国内常用NTP服务器地址及IP_环球新视野
- rocketdock怎么操作?rocketdock教程之程序设置-环球热消息
- 当前速读:QQ火炬手图标怎么关闭?关闭图标方法介绍
- 【世界速看料】戴森v7v8v10什么区别?V6和V8的区别介绍
- linux主机的详细介绍 linux主机安装的八个步骤_全球讯息
- 环球速读:富可视m310怎么刷机?富可视m310刷机教程
- 手机wifi密码破解器哪个好用?手机wifi密码破解器介绍
- 天天即时:淘宝拥有注册会员1.7亿 注册用户不断增长
- 手摇甘蔗榨汁机怎么样?品牌有哪些? 天天视讯
- 天天信息:linux内核编译ccflag,linux-内核编译 centisecs文件控制内核参数
- 全球今头条!连连支付怎么样?连连靠谱吗?
- AngularJS中的refresher该如何使用?使用技巧|动态
- 联想s720i配置怎么样?联想s720i配置总结|热文
- 【证书】PFX证书、CER证书申请流程详解
- dockerexec-itoracle11g创建容器实例分享
- 当前报道:功放如何连接?功放机接线图详解
- 手机无限重启或无法开机怎么办?索爱st25i强刷教程及注意事项 快报
- 头条:绿色出行新方式:共享汽车APP的交互体验
- 环球观焦点:B站视频播放源地址获取及B站视频下载
- 复旦壁纸:手绘正校门1024、7681280
- 佳能IP1180怎么样?佳能IP1180详情介绍
- 天天热门:象棋里的卧槽马是什么?典型案例分享
- 无法访问文件夹怎么办?无法访问文件夹的原因和解决方法-焦点速看
- 设计带构造函数的Dog类 对数据成员进行初始化
- 焦点报道:薛定谔的猫和EPR佯谬——量子力学史上的经典术语
- 网银无法登陆怎么办?网上银行登录安全控件
- 联想昭阳E46G能玩魔兽世界吗?显卡集显特效开起来根本没办法玩
- 最新:在百度里下载格式工厂——KuGo格式
- speedtest-cli|网速测试工具命令行方式
- 【数据更新】全国上网卡专属号段数据汇总
- 全球新动态:Calendar类:日历字段的转换方法
- 数据字典中的同义词:user_synonyms
- 非定常约束:几何约束与完整约束的区别
- 图片文件合成器是什么?图片、文件合成器的原理与方法
- 天天微头条丨企业的经营性现金流与净利润的含金量有多大?
- 微头条丨java timestamp 格式化_java日期处理(Timestamp)
- 【世界时快讯】《满江红》让杭州岳王庙成热门打卡地:秦桧像曾被砸烂9次
- 分享5个高质无损音乐网站 歌曲很丰富
- 徐宏芳:《警察抓小偷》网络游戏指法教学教案
- 全球热头条丨世界空间中的着色器 从对象空间到世界空间的转换
- 考研英语真题 翻译真题里的人名该怎么翻译?
- 【世界快播报】《如龙:维新!极》“复仇之刃”预告 全新截图欣赏
- 索尼承诺在PSVR2发行前“增加PS5主机供应”:全球要闻
- 郭明錤:可折叠iPad或明年问世,今年苹果可能不会发新品,出货至少下降10%
- Xbox金会员2月会免游戏公布 《为了吾王》等
- 兔年首个交易日,两大股东公告“抢筹”兴业银行
- 【世界热闻】曝百度将推人工智能聊天工具:类似ChatGPT
- 环球微动态丨腾讯游戏春节7天吸金破4.5亿:《王者荣耀》收入超3千万!
- 国产《时灵:星辰愚者》2月14日发售 登陆PS5/PC/NS
- 暴雪游戏国服“头七” 你找到合适的平替游戏了吗?
- 《流浪地球2》MOSS和末日铁拳是一个配音演员:给破球来个上勾拳!:世界快消息
- 【环球速看料】PS5广告:奎爷利维坦巨斧现身英国伦敦
- 效仿印尼,全球第二大镍生产国菲律宾考虑对镍出口征税
- 摩根士丹利“大空头”警告:不要参与反弹行情,美股熊市还没结束
- 消费者遭遇特步反向抹零 特步回应:系统设置四舍五入
- 超4000万!Capcom称当前财年销量有望是史上最高一年:全球即时看
- 最新:我爱我家2022年业绩预告:聚焦品质服务 推进精细运营
- 我家的春节泡汤了,因为家里有人没阳
- 《卧龙:苍天陨落》中有“黑暗熊猫”登场:不会伤人的可爱萌物-世界最新
- 快看点丨消费修复成色几何?
- 世界今日讯!以技术革新引领绿色制造 三菱电机助力碳中和愿景
- 颜值绝了!荣耀Magic5 Lite渲染图曝光
- 可折叠iPad将于2024年发布,使用碳纤维铰链:环球快资讯
- 天天新资讯:买一个游戏花 6000 块,玩完发现太值了?
- 在罐头里跑酷几十小时后,我成为了首席大法师_环球热点
- 前景悲观!德国四季末GDP同比初值 0.5%,环比下降0.2% 焦点快看
- “黑马”上位,这个西南省份终于等到了
- 【世界速看料】兔年首例券商高管变动,30年资深老将“告别”海通
- 性能炸裂!RTX 4090 Ti规格泄漏,总功率为600W,CUDA核心增加10%