Java管理SSL证书
SSL证书结构
根证书的生成分为三个部分:
- 生成根证书的公钥和私钥
- 构建证书的原始证书,包括公钥、加密算法、生效时间、过期时间等信息。
- 用根证书私钥对原始证书进行签名,生成合法的根证书。
- 根证书安装,将根证书安装到客户端,比如手机、电脑中。
代码
生成服务器证书
服务器证书的生成过程与根证书类似,只是给服务器原始证书签名的不是自己生成的私钥,而是根证书的私钥。
客户端证书校验过程
- 客户端收到服务端发送的服务器SSL证书。
- 解析获得服务器证书的颁发者
- 找到已安装在客户端的颁发者根证书,如果没找到则服务器证书非法,停止校验。
- 用根证书的公钥解析服务器证书的签名信息,完成解析认证成功,否则失败。
我们采用keytool生成相应的根秘钥库、服务器秘钥库、客户端秘钥库
1.从根秘钥库导出根原始证书;
2.从服务器秘钥库导出服务器原始证书;
3.从客户端秘钥库导出客户端原始证书;
4.制作根证书:采用java程序用根私钥对根原始证书签名,issuer与subject保持一致;
5.制作服务器证书:采用java程序用根私钥对服务器原始证书签名,subject的CN为服务器标识,表示专为某服务器签发;
6.制作客户端证书:采用java程序用根私钥对客户端原始证书签名,subject的CN为用户标识,表示专为某用户会话临时签发;
1生成根证书keytool -list -v -keystore client20210427.keystore -storepass 'clientPassword'1.1.生成秘钥
keytool -genkey -dname "CN=xx.domain.com, OU=domain, O=xx, L=bj, ST=cy, C=China" -alias root-alias -keypass 'rootPassword' -keyalg RSA -keystore root-key.store -validity 36001.2.生成根原始证书 service.cer
keytool -export -alias root-alias -storepass 'rootPassword' -file root-src.cer -keystore root-key.store1.3.java程序用根私钥对原始证书进行签名2生成服务器证书
2.1.生成服务器秘钥
keytool -genkey -dname "CN=xx.domain.com, OU=domain, O=xx, L=bj, ST=cy, C=China" -alias server-alias -keyalg RSA -keystore server-key.store -keypass 'serverPassword' -storepass 'serverPassword' -validity 1100
clientPassword
2.2.生成服务器原始证书 service.cer
keytool -export -alias server-alias -storepass 'serverPassword' -file server-src.cer -keystore server-key.store2.3.java程序用根私钥对原始证书进行签名3生成客户端证书
3.1.生成客户端秘钥
keytool -genkey -dname "CN=xx.domain.com, OU=domain, O=xx, L=bj, ST=cy, C=China" -alias client-alias -keyalg RSA -keystore client-key.store -keypass 'clientPassword' -storepass 'clientPassword' -validity 11003.2.生成客户端原始证书 service.cer
keytool -export -alias client-alias -storepass 'clientPassword' -file client-src.cer -keystore client-key.store3.3.java程序用根私钥对原始证书进行签名导出数字证书
keytool -exportcert -alias myCertificate -keystore myKeystore.keystore -file myCer.cer -rfc
各参数含义如下:
-exportcert 表示证书导出操作
-alias 指定别名
-keystore 指定密钥库文件
-file 指定导出证书的文件路径
-rfc 指定以Base64编码格式输出打印证书查看数字证书方法
keytool -printcert -file client.cer再用openssl 验证一下是否正常
openssl x509 -inform DER -in root-sign.cer -text -nooutsubject
C=China, ST=cy, L=bj, O=xx, OU=domain, CN=xx.domain.com
所有代码在jdk1.8下验证完成
/*** 获取证书信息,并自签名待签证书 这里是自签名 得到根证书** @param certPath : 待签证书地址* @throws Exception*/public X509CertInfo createRootCert(String certPath) throws Exception {// 获取待签名证书FileInputStream is = new FileInputStream(certPath);CertificateFactory vCertFactory = CertificateFactory.getInstance("X.509");Certificate certificate = vCertFactory.generateCertificate(is);is.close();byte[] certData = certificate.getEncoded();// 设置签名证书信息:有效日期、序列号、签名者、数字签名算发X509CertImpl certImpl = new X509CertImpl(certData);X509CertInfo cert = (X509CertInfo) certImpl.get(X509CertImpl.NAME + "." + X509CertImpl.INFO);cert.set(X509CertInfo.VALIDITY, getCertValidity());cert.set(X509CertInfo.SERIAL_NUMBER, getCertSerualNumber());cert.set(X509CertInfo.ISSUER + "." + CertificateIssuerName.DN_NAME, cert.get(X509CertInfo.SUBJECT + "." + CertificateIssuerName.DN_NAME));cert.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, getAlgorithm());return cert;}
签发
/*** 取得待签证书信息,并签名待签证书** @throws Exception*/public X509CertInfo signCert(CertInfo ci, X509CertInfo cert, String certSavePath) throws Exception {X509CertImpl certImpl = new X509CertImpl(cert);// 生成新正书验证码certImpl.sign(ci.getPk(), "MD5WithRSA");BASE64Encoder base64 = new BASE64Encoder();File file = new File(certSavePath);file.createNewFile();FileOutputStream os = new FileOutputStream(certSavePath);base64.encodeBuffer(certImpl.getEncoded(), os);// certImpl.derEncode(os);os.close();return cert;}public X509CertInfo signCert2(CertInfo ci, X509CertInfo cert, String certSavePath) throws Exception {X509CertImpl certImpl = new X509CertImpl(cert);// 生成新正书验证码certImpl.sign(ci.getPk(), "MD5WithRSA");FileUtil.writeToFile(certSavePath, certImpl.getEncoded());return cert;}public String signCertBase64(CertInfo ci, X509CertInfo cert) throws Exception {X509CertImpl certImpl = new X509CertImpl(cert);// 生成新正书验证码certImpl.sign(ci.getPk(), "MD5WithRSA");BASE64Encoder encoder = new BASE64Encoder();String encoded = encoder.encode(certImpl.getEncoded());StringBuilder sb = new StringBuilder();sb.append("-----BEGIN RSA PRIVATE KEY-----\r\n");sb.append(encoded);sb.append("\r\n-----END RSA PRIVATE KEY-----");return sb.toString();}
创建证书
X509CertInfo info = new X509CertInfo();
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(new java.util.Random().nextInt() & 0x7fffffff));
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(AlgorithmId.get("SHA256withRSA")));
info.set(X509CertInfo.SUBJECT, subject);
info.set(X509CertInfo.KEY, new CertificateX509Key(subjectKeyPair.getPublic()));
info.set(X509CertInfo.VALIDITY, validity);
info.set(X509CertInfo.ISSUER, x509Certificate.getIssuerDN());
创建X509CertInfo.SUBJECT 证书使用者信息
/*** 创建证书使用者信息* @param CN comonName* @param OU organizationalUnitName* @param O organizationName* @param C countryName* @param L localityName* @param ST stateOrProvinceName* @return* @throws IOException*/public static X500Name createSubject(String CN,String OU,String O,String C,String L,String ST) throws IOException {X500Name subject = new X500Name(new StringBuilder().append("CN=").append(CN).append(",OU=").append(OU).append(",O=").append(O).append(",C=").append(C).append(",L=").append(L).append(",ST=").append("abc").toString());return subject;}
对原始证书签名,并签入使用者信息,这里subject就是使用者信息,签名采用根证书私钥
public X509CertInfo createCert(String pin, InputStream is) throws Exception {X500Name subject = createSubject(new SignInfo(), pin);// 获取待签名证书CertificateFactory vCertFactory = CertificateFactory.getInstance("X.509");Certificate certificate = vCertFactory.generateCertificate(is);is.close();byte[] certData = certificate.getEncoded();// 设置签名证书信息:有效日期、序列号、签名者、数字签名算发X509CertImpl certImpl = new X509CertImpl(certData);X509CertInfo cert = (X509CertInfo) certImpl.get(X509CertImpl.NAME + "." + X509CertImpl.INFO);cert.set(X509CertInfo.VALIDITY, getCertValidity());cert.set(X509CertInfo.SERIAL_NUMBER, getCertSerualNumber());cert.set(X509CertInfo.ISSUER + "." + CertificateIssuerName.DN_NAME, cert.get(X509CertInfo.SUBJECT + "." + CertificateIssuerName.DN_NAME));cert.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, getAlgorithm());cert.set(X509CertInfo.SUBJECT, subject);return cert;
}
maven 打包证书的过程中不断提示:IOException: Invalid keystore format
做以下两步操作即可解决
设置不替换的变量:p12 jks
这个p12是后缀的意思,不想让他去修改什么文件,就在这里面添加条目即可
<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><configuration><nonFilteredFileExtensions><nonFilteredFileExtension>p12</nonFilteredFileExtension><nonFilteredFileExtension>jks</nonFilteredFileExtension></nonFilteredFileExtensions></configuration>
</plugin>
这样签发的证书在linux完美通过验证,but在windows上不能通过验证,于是我们对linux和windows上的证书格式进行比较,发现windows上根证书必须要包含X509v3 Basic Constraints,CA:True
private CertificateExtensions createCertificateExtensions2() throws IOException {CertificateExtensions exts = new CertificateExtensions();BasicConstraintsExtension bce = new BasicConstraintsExtension(true, true, -1);exts.set(BasicConstraintsExtension.NAME, new BasicConstraintsExtension(false, bce.getExtensionValue()));return exts;}//对根证书签名代码增加如下一行,写入extensioncert.set(X509CertInfo.EXTENSIONS, extensions);
参考
https://www.jianshu.com/p/ed6486f0e608
https://blog.csdn.net/JustinQin/article/details/100052500
https://blog.csdn.net/jxctx/article/details/45970199
Java管理SSL证书相关推荐
- 用XCA(X Certificate and key management)可视化程序管理SSL 证书(3)--创建自己定义的凭证管理中心(Certificate Authority)...
在第"用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)---创建证书请求"章节中,我们介绍了怎样用XCA创建SSL证书请 ...
- 用XCA(X Certificate and key management)可视化程序管理SSL 证书(1)--安装XCA
一般情况下,大家能想到管理SSL证书的方法就是OpenSSL程序或者用JDK自带的keytool命令,但是这两种工具虽然功能强大,但是用户的可操作行并不好, 需要用户属性一些命令的用法,而且也不是特别 ...
- java 忽略SSL证书
** java 忽略SSL证书 ** 代码如下:(网上借鉴了很多大神的写法,都不能实现,最终使用以下代码亲测可行,侵联删) ```java import org.apache.http.Header; ...
- 用XCA(X Certificate and key management)可视化程序管理SSL 证书(3)--创建自定义的凭证管理中心(Certificate Authority)
在第"用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)---创建证书请求"章节中,我们介绍了如何用XCA创建SSL证书请 ...
- 用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)--生成SSL证书请求...
在上个章节中,我们提到了怎样安装XCA(X Certificate and key management)程序.这个章节我们開始正式介绍怎样用XCA生成证书请求.假设大家用过java的话.肯定知道jd ...
- JAVA通过SSL证书创建MS AD账户及设置密码
近期由于工作需要整理一下自动化的东西,因为公司去年上线了OA,所以公司的入职系统会提交用户的信息到IT部门,最早的做法是入职到了,IT部门收集用户信息在AD中创建对应的用户信息,所以为了提高管理员的工 ...
- 用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)--生成SSL证书请求
在上个章节中,我们提到了如何安装XCA(X Certificate and key management)程序,这个章节我们开始正式介绍如何用XCA生成证书请求.如果大家用过java的话,肯定知道jd ...
- java生成ssl证书和部署
自签名SSL证书的生成 自签证书虽然提示:不安全.但还是有很多的好处,所以下面先说说自签证书的生成,主要使用Java JDK下的:keytool.exe 2:安装完后,根据实际的路径找到keytool ...
- Java生成SSL证书
1. 背景 2. 演示环境 3. 命令 4. 创建证书 5. 查看证书 5.1. 显示详细 5.2. 编码打印 6. 导入导出证书 6.1. 导出 6.2. 导入 7. 修改密码 7.1. 修改密钥库 ...
最新文章
- django模板中使用JQ代码实现瀑布流显示效果
- mof格式的文件怎么打开?用什么工具?
- CIPAddressCtrl类的使用(IP地址与CString的互相转化)
- python函数调用语句_Python函数定义和函数调用
- java构造函数重载继承_Java基础-继承 - 写代码换盆的个人空间 - OSCHINA - 中文开源技术交流社区...
- 小程序根据手机机型设置自定义底部导航距离
- pandas 读写 excel
- 在四个小时内组装好这个游戏机
- 传输层协议的UDP和TCP
- systemctl不可用时,使用service命令关闭防火墙
- 在kali下对Windows 卷没有写权限的解决办法
- 第9月第6天 push pop动画 生成器模式(BUILDER)
- radius认证服务器部署linux,CentOS安装配置radius服务器
- Codeforces Round#767(Div.2) F1. Game on Sum (Easy Version)
- 发布QtCsv文件转语言翻译文件工具
- Blazor在IoT领域的前端实践 @.NET开发者日
- mac设置共享屏幕 苹果mac屏幕共享设置详细教程
- 《C++ 笔记》 Part5 C++ 资源大全中文版
- 程序人生 - 库克:苹果收取 30% 佣金很合理!
- uniapp onReachBottom 不触发
热门文章
- 世界各国犯罪率统计系列:各国暴力犯罪性犯罪(2003-2021)
- 通俗易懂说带宽、网速
- gitolite 搭建Android仓库(三)
- idm动不动就弹出注册码已失效,怎么解决
- 魔兽怀旧卓越服务器微信,魔兽怀旧服:TBC别选这几个服务器,很有可能排几个小时都进不去...
- 超超简单的Arcgis10.8软件安装包及安装步骤
- 深入Mysql字符集设置
- Python Selenium UI自动化 ⽂件上传
- MFRC63002HN国产替代,软硬件兼容,无需改软件,性价比超高,不缺货。
- 雷军:中国的乔布斯?!--没人看我来转,疑似水文,太晚了,稍侯拍砖