IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Java 生成X.509 V3证书 -> 正文阅读

[网络协议]Java 生成X.509 V3证书

使用Java语言生成X.509 V3证书

1. X.509 V3证书

X.509 是公钥证书的格式标准, 广泛用于 TLS/SSL 安全通信或者其他需要认证的环境中。
X.509 证书可以由 CA(Certificate Authority,数字证书认证机构)颁发,也可以自签名产生。

X.509 证书中主要含有公钥、身份信息、签名信息和有效性信息等信息。
这些信息用于构建一个验证公钥的体系,用来保证客户端得到的公钥正是它期望的公钥。

  • 公钥 : 非对称密码中的公钥。公钥证书的目的就是为了在互联网上分发公钥。
  • 身份信息 : 公钥对应的私钥持有者的信息,域名以及用途等。
  • 签名信息 : 对公钥进行签名的信息,提供公钥的验证链。可以是 CA
    的签名或者是自签名,不同之处在于CA证书的根证书大都内置于操作系统或者浏览器中,而自签名证书的公钥验证链则需要自己维护(手动导入到操作系统中或者再验证流程中单独提供自签名的根证书)。
  • 有效性信息:证书的有效时间区间,以及 CRL(证书吊销列表)等相关信息。
    X.509 证书的标准规范RFC5280中详细描述了证书的 Encoding Format(编码格式)和
    Structure(证书结构)。

1.1 编码格式

  • DER格式 : 二进制格式。
  • PEM格式 : ASCII 文本格式。在 DER 格式或者其他二进制数据的基础上,使用 base64 编码为 ASCII 文本,以便于在仅支持 ASCII
    的环境中使用二进制的 DER 编码的数据。

1.2 X.509证书结构

Certificate
  Version Number
  Serial Number
  Signature Algorithm ID
  Issuer Name
  Validity period
  Not Before
  Not After
  Subject name
  Subject Public Key Info
  Public Key Algorithm
  Subject Public Key
  Issuer Unique Identifier (optional)
  Subject Unique Identifier (optional)
  Extensions (optional)
...
Certificate Signature Algorithm
Certificate Signature

1.3 X.509 证书相关文件常见的扩展名

  • .pem : 隐私增强型电子邮件格式(缩写:PEM)格式,通常是由证书的 DER 二进制 Base64 编码得出。(最常用)。
  • .key : PEM 格式的私钥文件。
  • .pub : PEM 格式的公钥文件。
  • .crt : PEM 格式的公钥证书文件,也可能是 DER。
  • .cer : DER 格式的公钥证书文件,也可能是 PEM。
  • .crs : PEM 格式的 CSR 文件,也可能是 DER。
  • .p12 – PKCS#12 格式,包含证书的同时可能还包含私钥。
  • .pfx – PFX,PKCS#12 之前的格式(通常用PKCS#12格式,比如由互联网信息服务产生的 PFX 文件)。

提示:
目前一般使用pem格式的证书。
大多数系统会根据证书文件中的内容来识别具体的格式,而不依赖于扩展名。

更多信息请参考:维基百科X.509

2. 使用Java生成X.509 V3 证书

2.1 引入依赖

如果使用 Maven 项目,则需要在 pom.xml 中引入下面的依赖:


<dependencies>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.70</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-ext-jdk15on</artifactId>
        <version>1.70</version>
    </dependency>
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.11.0</version>
    </dependency>
</dependencies>

bouncycastle 是一个 JCE Provider,实现了常用的加密算法,是一个加密算法库,同时提供了 X.509 证书生成的一些帮助类。

2.2 代码实现

下面是一个例子:

import org.apache.commons.io.FileUtils;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x509.Certificate;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.Base64;
import java.util.Date;

public class App {
    /**
     * 生成自签名的PEM格式的证书和私钥文件
     */
    public static void main(String[] args) throws OperatorCreationException, IOException {
        //生成主题信息
        X500Name subject = generateSubject("CN", "Beijing", "Beijing", "", "", "www.test.com");
        //生成RSA密钥对
        KeyPair keyPair = generateRsaKeyPair(2048);
        assert keyPair != null;
        PublicKey aPublic = keyPair.getPublic();
        PrivateKey aPrivate = keyPair.getPrivate();
        //下面是私钥key生成的过程
        byte[] privateKeyEncode = aPrivate.getEncoded();
        String privateKeyStr = Base64.getEncoder().encodeToString(privateKeyEncode);
        String privateKeyFileContent = "" +
                "-----BEGIN RSA PRIVATE KEY-----\n" +
                lf(privateKeyStr, 64) +
                "-----END RSA PRIVATE KEY-----";
        FileUtils.write(new File("C:\\Users\\Administrator\\Desktop\\test1.key"), privateKeyFileContent,
                StandardCharsets.UTF_8);
        //下面是PEM格式的证书生成过程
        long currTimestamp = System.currentTimeMillis();
        X500Name issuer = subject;
        X509v3CertificateBuilder x509v3CertificateBuilder = new JcaX509v3CertificateBuilder(
                issuer, BigInteger.valueOf(System.currentTimeMillis()),
                new Date(currTimestamp), new Date(currTimestamp + (long) 365 * 24 * 60 * 60 * 1000),
                subject, aPublic);
        JcaContentSignerBuilder sha256WITHRSA = new JcaContentSignerBuilder("SHA256WITHRSA");
        ContentSigner contentSigner = sha256WITHRSA.build(aPrivate);
        X509CertificateHolder x509CertificateHolder = x509v3CertificateBuilder.build(contentSigner);
        Certificate certificate = x509CertificateHolder.toASN1Structure();
        byte[] encoded = certificate.getEncoded();
        String certStr = Base64.getEncoder().encodeToString(encoded);
        String certFileContent = "" +
                "-----BEGIN CERTIFICATE-----\n" +
                lf(certStr, 64) +
                "-----END CERTIFICATE-----";
        FileUtils.write(new File("C:\\Users\\Administrator\\Desktop\\test1.pem"), certFileContent,
                StandardCharsets.UTF_8);
    }

    /**
     * 生成Subject信息
     *
     * @param C  Country Name (国家代号),eg: CN
     * @param ST State or Province Name (洲或者省份),eg: Beijing
     * @param L  Locality Name (城市名),eg: Beijing
     * @param O  Organization Name (可以是公司名称),eg: 北京创新乐知网络技术有限公司
     * @param OU Organizational Unit Name (可以是单位部门名称)
     * @param CN Common Name (服务器ip或者域名),eg: 192.168.30.71 or www.baidu.com
     * @return X500Name Subject
     */
    public static X500Name generateSubject(String C, String ST, String L,
                                           String O, String OU, String CN) {
        X500NameBuilder x500NameBuilder = new X500NameBuilder();
        x500NameBuilder.addRDN(BCStyle.C, C);
        x500NameBuilder.addRDN(BCStyle.ST, ST);
        x500NameBuilder.addRDN(BCStyle.L, L);
        x500NameBuilder.addRDN(BCStyle.O, O);
        x500NameBuilder.addRDN(BCStyle.OU, OU);
        x500NameBuilder.addRDN(BCStyle.CN, CN);
        return x500NameBuilder.build();
    }

    public static KeyPair generateRsaKeyPair(int keySize) {
        try {
            KeyPairGenerator rsa = KeyPairGenerator.getInstance("RSA");
            rsa.initialize(keySize);
            return rsa.generateKeyPair();
        } catch (NoSuchAlgorithmException ignore) {
        }
        return null;
    }

    public static String lf(String str, int lineLength) {
        assert str != null;
        assert lineLength > 0;
        StringBuilder sb = new StringBuilder();
        char[] chars = str.toCharArray();
        int n = 0;
        for (char aChar : chars) {
            sb.append(aChar);
            n++;
            if (n == lineLength) {
                n = 0;
                sb.append("\n");
            }
        }
        if (n != 0)
            sb.append("\n");
        return sb.toString();
    }
}

运行上面的代码,将生成两个文件:test1.pem(证书)和test1.key(私钥)。
如果使用 windows 系统,请更改 test1.pem 后缀为 .cert,然后双击该文件即可打开。

证书详情

可以看到证书中的一些信息。

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:34:57  更:2022-10-31 12:39:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 13:17:38-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码