当前位置: 首页 > news >正文

【SSL】什么是自签名证书及使用Java生成SSL自签名证书

【SSL】使用Java生成SSL自签名证书

  • 1.自签名证书介绍
    • 1.1 什么是自签名证书
    • 1.2 主要作用
  • 2.代码实现
    • 2.1 添加pom.xml
    • 2.1 初始化Bouncy Castle 扩展
    • 2.2 生成自签名证书
      • 2.2.1 证书生成核心代码
      • 2.2.2 转化为通用的证书、公钥、私钥格式
    • 3.完整实现

1.自签名证书介绍

1.1 什么是自签名证书

特性维度自签名证书CA签发证书
颁发者使用者自己受信任的CA机构颁发
信任机制需要手动在各客户端信任,​不被浏览器/操作系统默认信任​被操作系统和浏览器预置根证书全局信任​
成本免费按年付费
签发速度随时生成不同版本签发效率不同
安全性存在显著风险安全性高具有OSSP、CRL
适用场景内部测试、开发环境、内网等公网

1.2 主要作用

  • 本地开发与测试环境​

    这是自签名证书最常用也最合适的场景。在开发网站或应用程序时,如果需要测试HTTPS功能(例如,测试单点登录SSO、支付回调等),配置受信任的CA证书流程繁琐。使用自签名证书可以快速搭建一个加密的测试环境,确保功能开发顺利进行

  • 封闭的内部网络应用​

    对于一些仅限于内部员工访问的系统,如公司内网的Wiki、监控平台、设备管理后台等,如果所有访问客户端(如员工电脑)可以统一安装并信任该自签名证书,那么它也能提供安全的加密通信,同时节省成本

  • ​物联网设备初始配置与内部通信​

    一些智能物联网设备在初次启动配置时,可能会使用自签名证书提供一个临时的加密通道在微服务架构或设备集群内部,服务间的通信有时也会使用自签名证书进行身份验证和加密。

2.代码实现

2.1 添加pom.xml

<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version> <!-- 请使用最新稳定版本 -->
</dependency>

2.1 初始化Bouncy Castle 扩展

static {Security.addProvider(new BouncyCastleProvider());}

2.2 生成自签名证书

public static Map<String, String> gen(String commonName, String o, String i, String st) throws Exception {Map<String, String> certMap = Maps.newHashMap();// 1. 生成RSA密钥对KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", CertToolConstants.ECC_BC_STR);kpg.initialize(2048);KeyPair keyPair = kpg.generateKeyPair();// 2. 生成自签名证书Certificate cert = generateSelfSignedCertificate(keyPair, commonName, o, i, st);// 3. 转换为PEM格式并返回certMap.put("证书文件", encodeCertificateToPEMString(cert));certMap.put("私钥", encodePrivateKeyToPEMString(keyPair.getPrivate()));certMap.put("公钥", encodeKeyToPEMString(keyPair.getPublic()));return certMap;
}

2.2.1 证书生成核心代码

public static Certificate generateSelfSignedCertificate(KeyPair keyPair, String commonName, String O, String l, String st) throws Exception {X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();X500Principal dnName = new X500Principal("CN=" + commonName + ", OU=IT Dept, O=" + O + ", L=" + l + ", ST=" + st + ", C=CN");X500Principal is = new X500Principal("CN=xzq717.com, OU=IT Dept, O=Xcc Trust OV, L=Beijing, ST=Beijing, C=CN");//自签名证书序列号certGen.setSerialNumber(BigInteger.probablePrime(128, new SecureRandom()));certGen.setIssuerDN(dnName);        // 颁发者certGen.setSubjectDN(is);           // 证书主体certGen.setPublicKey(keyPair.getPublic());certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");//设置证书开始日期certGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24));//设置证书截止日期certGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365)));certGen.addExtension(org.bouncycastle.asn1.x509.Extension.basicConstraints, true, new org.bouncycastle.asn1.x509.BasicConstraints(true));return certGen.generate(keyPair.getPrivate(), CertToolConstants.ECC_BC_STR);
}

2.2.2 转化为通用的证书、公钥、私钥格式

public static String toPemString(byte[] contentBytes, String type) throws IOException {StringWriter stringWriter = new StringWriter();try (PemWriter pemWriter = new PemWriter(stringWriter)) {PemObject pemObject = new PemObject(type, contentBytes);pemWriter.writeObject(pemObject);}return stringWriter.toString();}public static String encodeCertificateToPEMString(Certificate certificate) throws Exception {return toPemString(certificate.getEncoded(), "CERTIFICATE");}public static String encodeKeyToPEMString(PublicKey publicKey) throws Exception {X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey.getEncoded());return toPemString(keySpec.getEncoded(), "PUBLIC KEY");}public static String encodePrivateKeyToPEMString(PrivateKey privateKey) throws Exception {PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());return toPemString(keySpec.getEncoded(), "PRIVATE KEY");}

3.完整实现

package com.xzq717.utils;import com.google.common.collect.Maps;
import com.xcc.tools.constants.CertToolConstants;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import org.bouncycastle.x509.X509V3CertificateGenerator;import javax.security.auth.x500.X500Principal;
import java.io.FileWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.Certificate;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;public class SelfSignedCertGenerator {static {Security.addProvider(new BouncyCastleProvider());}public static Certificate generateSelfSignedCertificate(KeyPair keyPair, String commonName, String O, String l, String st) throws Exception {X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();X500Principal dnName = new X500Principal("CN=" + commonName + ", OU=IT Dept, O=" + O + ", L=" + l + ", ST=" + st + ", C=CN");X500Principal is = new X500Principal("CN=xzq717.com, OU=IT Dept, O=Xcc Trust OV, L=Beijing, ST=Beijing, C=CN");certGen.setSerialNumber(BigInteger.probablePrime(128, new SecureRandom()));certGen.setIssuerDN(dnName);certGen.setSubjectDN(is);certGen.setPublicKey(keyPair.getPublic());certGen.setSignatureAlgorithm("SHA256WithRSAEncryption");certGen.setNotBefore(new Date(System.currentTimeMillis() - 1000L * 60 * 60 * 24));certGen.setNotAfter(new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365)));certGen.addExtension(org.bouncycastle.asn1.x509.Extension.basicConstraints, true, new org.bouncycastle.asn1.x509.BasicConstraints(true));return certGen.generate(keyPair.getPrivate(), CertToolConstants.ECC_BC_STR);}public static Map<String, String> gen(String commonName, String o, String i, String st) throws Exception {Map<String, String> certMap = Maps.newHashMap();KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", CertToolConstants.ECC_BC_STR);kpg.initialize(2048);KeyPair keyPair = kpg.generateKeyPair();Certificate cert = generateSelfSignedCertificate(keyPair, commonName, o, i, st);// 保存为 PEM 文件certMap.put("证书文件", encodeCertificateToPEMString(cert));certMap.put("私钥", encodePrivateKeyToPEMString(keyPair.getPrivate()));certMap.put("公钥", encodeKeyToPEMString(keyPair.getPublic()));return certMap;}public static String toPemString(byte[] contentBytes, String type) throws IOException {StringWriter stringWriter = new StringWriter();try (PemWriter pemWriter = new PemWriter(stringWriter)) {PemObject pemObject = new PemObject(type, contentBytes);pemWriter.writeObject(pemObject);}return stringWriter.toString();}public static String encodeCertificateToPEMString(Certificate certificate) throws Exception {return toPemString(certificate.getEncoded(), "CERTIFICATE");}public static String encodeKeyToPEMString(PublicKey publicKey) throws Exception {X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey.getEncoded());return toPemString(keySpec.getEncoded(), "PUBLIC KEY");}public static String encodePrivateKeyToPEMString(PrivateKey privateKey) throws Exception {PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());return toPemString(keySpec.getEncoded(), "PRIVATE KEY");}}
http://www.dtcms.com/a/569381.html

相关文章:

  • 从繁琐到高效:文档抽取技术驱动医疗健康行业的数字化转型
  • 做网站 阿里云河南推广网站
  • 在VSCode+Guider基础上:拖动滑条控件,显示滑条数值
  • 斯坦福大学 | CS336 | 从零开始构建语言模型 | Spring 2025 | 笔记 | Lecture 7: Parallelism 1
  • cookie、session、token、JWT(JSON Web Token)
  • 免费学平面设计的网站如何开设一个网站
  • WebGIS开发智慧校园(14)地图控件的添加
  • Agent Demo初体验
  • Cursor 项目实战:AI播客策划助手开发指南(一)——需求分析与功能原型
  • 当AI遇上Python:重新定义编程学习的《AIGC高效编程:Python从入门到高手》
  • 成都上界品牌设计事务所小红书搜索优化
  • Apache Calcite查询规划
  • Linux网络——传输层协议UDPTCP
  • useState 真的那么简单吗?我在项目里踩过的坑
  • 如何用5种实用方法将电脑上的音乐传输到安卓手机
  • 做网页到哪个网站找素材物流网站有哪些
  • MP4视频播放问题
  • HR8837:赋能低压直流电机的高效安全驱动芯片
  • Linux源码安装FFmpeg和av库
  • 亳州市城乡建设局网站ps设计网站首页效果图
  • Syncthing Linux 部署教程
  • 做疏通什么网站推广好网页制作软件 ad
  • html 和css基础常用的标签和样式(2)-css
  • 【数据集】【YOLO】【目标检测】共享单车数据集,共享单车识别数据集 3596 张,YOLO自行车识别算法实战训推教程。
  • Coze-AI智能体开发平台5-Coze的API与SDK
  • 河南网站建设优化技术网站建设与维护学什么科目
  • 超越简单的回放:深度解析国标GB28181算法算力平台EasyGBS的录像检索与回放技术
  • HCIP Datacom 认证难度高吗?零基础能考吗?
  • 代码实战:PHP爬虫抓取信息及反爬虫API接口
  • CentOS 7 停止维护后 YUM 源配置速查手册