赞
踩
X.509 是公钥证书的格式标准, 广泛用于 TLS/SSL 安全通信或者其他需要认证的环境中。
X.509 证书可以由 CA(Certificate Authority,数字证书认证机构)颁发,也可以自签名产生。
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
提示:
目前一般使用pem格式的证书。
大多数系统会根据证书文件中的内容来识别具体的格式,而不依赖于扩展名。
更多信息请参考:维基百科X.509
如果使用 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 证书生成的一些帮助类。
下面是一个例子:
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 后缀为 .crt,然后双击该文件即可打开。
可以看到证书中的一些信息。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。