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证书相关推荐

  1. 用XCA(X Certificate and key management)可视化程序管理SSL 证书(3)--创建自己定义的凭证管理中心(Certificate Authority)...

    在第"用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)---创建证书请求"章节中,我们介绍了怎样用XCA创建SSL证书请 ...

  2. 用XCA(X Certificate and key management)可视化程序管理SSL 证书(1)--安装XCA

    一般情况下,大家能想到管理SSL证书的方法就是OpenSSL程序或者用JDK自带的keytool命令,但是这两种工具虽然功能强大,但是用户的可操作行并不好, 需要用户属性一些命令的用法,而且也不是特别 ...

  3. java 忽略SSL证书

    ** java 忽略SSL证书 ** 代码如下:(网上借鉴了很多大神的写法,都不能实现,最终使用以下代码亲测可行,侵联删) ```java import org.apache.http.Header; ...

  4. 用XCA(X Certificate and key management)可视化程序管理SSL 证书(3)--创建自定义的凭证管理中心(Certificate Authority)

    在第"用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)---创建证书请求"章节中,我们介绍了如何用XCA创建SSL证书请 ...

  5. 用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)--生成SSL证书请求...

    在上个章节中,我们提到了怎样安装XCA(X Certificate and key management)程序.这个章节我们開始正式介绍怎样用XCA生成证书请求.假设大家用过java的话.肯定知道jd ...

  6. JAVA通过SSL证书创建MS AD账户及设置密码

    近期由于工作需要整理一下自动化的东西,因为公司去年上线了OA,所以公司的入职系统会提交用户的信息到IT部门,最早的做法是入职到了,IT部门收集用户信息在AD中创建对应的用户信息,所以为了提高管理员的工 ...

  7. 用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)--生成SSL证书请求

    在上个章节中,我们提到了如何安装XCA(X Certificate and key management)程序,这个章节我们开始正式介绍如何用XCA生成证书请求.如果大家用过java的话,肯定知道jd ...

  8. java生成ssl证书和部署

    自签名SSL证书的生成 自签证书虽然提示:不安全.但还是有很多的好处,所以下面先说说自签证书的生成,主要使用Java JDK下的:keytool.exe 2:安装完后,根据实际的路径找到keytool ...

  9. Java生成SSL证书

    1. 背景 2. 演示环境 3. 命令 4. 创建证书 5. 查看证书 5.1. 显示详细 5.2. 编码打印 6. 导入导出证书 6.1. 导出 6.2. 导入 7. 修改密码 7.1. 修改密钥库 ...

最新文章

  1. django模板中使用JQ代码实现瀑布流显示效果
  2. mof格式的文件怎么打开?用什么工具?
  3. CIPAddressCtrl类的使用(IP地址与CString的互相转化)
  4. python函数调用语句_Python函数定义和函数调用
  5. java构造函数重载继承_Java基础-继承 - 写代码换盆的个人空间 - OSCHINA - 中文开源技术交流社区...
  6. 小程序根据手机机型设置自定义底部导航距离
  7. pandas 读写 excel
  8. 在四个小时内组装好这个游戏机
  9. 传输层协议的UDP和TCP
  10. systemctl不可用时,使用service命令关闭防火墙
  11. 在kali下对Windows 卷没有写权限的解决办法
  12. 第9月第6天 push pop动画 生成器模式(BUILDER)
  13. radius认证服务器部署linux,CentOS安装配置radius服务器
  14. Codeforces Round#767(Div.2) F1. Game on Sum (Easy Version)
  15. 发布QtCsv文件转语言翻译文件工具
  16. Blazor在IoT领域的前端实践 @.NET开发者日
  17. mac设置共享屏幕 苹果mac屏幕共享设置详细教程
  18. 《C++ 笔记》 Part5 C++ 资源大全中文版
  19. 程序人生 - 库克:苹果收取 30% 佣金很合理!
  20. uniapp onReachBottom 不触发

热门文章

  1. 世界各国犯罪率统计系列:各国暴力犯罪性犯罪(2003-2021)
  2. 通俗易懂说带宽、网速
  3. gitolite 搭建Android仓库(三)
  4. idm动不动就弹出注册码已失效,怎么解决
  5. 魔兽怀旧卓越服务器微信,魔兽怀旧服:TBC别选这几个服务器,很有可能排几个小时都进不去...
  6. 超超简单的Arcgis10.8软件安装包及安装步骤
  7. 深入Mysql字符集设置
  8. Python Selenium UI自动化 ⽂件上传
  9. MFRC63002HN国产替代,软硬件兼容,无需改软件,性价比超高,不缺货。
  10. 雷军:中国的乔布斯?!--没人看我来转,疑似水文,太晚了,稍侯拍砖