使用 Java 生成证书、公钥和私钥 [已关闭]
我正在寻找一个java库或代码来动态生成证书,公钥和私钥,而无需使用第三方程序(例如openssl)。
我认为有些东西正在做keytool + openssl,但来自Java代码。
考虑一个基于 java servlet 的 Web 应用程序,该应用程序使用 ssl 和客户端身份验证进行保护。我希望 servlet 容器仅使用 Java 代码根据请求生成客户端证书(例如 pkcs12 格式)。
我正在寻找一个java库或代码来动态生成证书,公钥和私钥,而无需使用第三方程序(例如openssl)。
我认为有些东西正在做keytool + openssl,但来自Java代码。
考虑一个基于 java servlet 的 Web 应用程序,该应用程序使用 ssl 和客户端身份验证进行保护。我希望 servlet 容器仅使用 Java 代码根据请求生成客户端证书(例如 pkcs12 格式)。
您可以使用一对或多个密钥在 java 中动态生成证书。(公钥、私钥)。将这些密钥作为 BigInteger 格式获取,并检查以下代码以生成证书。
RSAPrivateKeySpec serPrivateSpec = new RSAPrivateKeySpec(
new BigInteger(val of pub key), new BigInteger(val of pri key));
fact = KeyFactory.getInstance("RSA");
PrivateKey serverPrivateKey = fact.generatePrivate(serPrivateSpec);
RSAPublicKeySpec serPublicSpec = new RSAPublicKeySpec(
new BigInteger(agentCL.getSerPubMod()), new BigInteger(agentCL.getSerPubExp()));
PublicKey serverPublicKey = fact.generatePublic(serPublicSpec);
keyStore = KeyStore.getInstance(IMXAgentCL.STORE_TYPE);
keyStore.load(null, SOMEPWD.toCharArray());
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
X509Certificate[] serverChain = new X509Certificate[1];
X509V3CertificateGenerator serverCertGen = new X509V3CertificateGenerator();
X500Principal serverSubjectName = new X500Principal("CN=OrganizationName");
serverCertGen.setSerialNumber(new BigInteger("123456789"));
// X509Certificate caCert=null;
serverCertGen.setIssuerDN(somename);
serverCertGen.setNotBefore(new Date());
serverCertGen.setNotAfter(new Date());
serverCertGen.setSubjectDN(somename);
serverCertGen.setPublicKey(serverPublicKey);
serverCertGen.setSignatureAlgorithm("MD5WithRSA");
// certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false,new
// AuthorityKeyIdentifierStructure(caCert));
serverCertGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
new SubjectKeyIdentifierStructure(serverPublicKey));
serverChain[0] = serverCertGen.generateX509Certificate(serverPrivateKey, "BC"); // note: private key of CA
keyStore.setEntry("xyz",
new KeyStore.PrivateKeyEntry(serverPrivateKey, serverChain),
new KeyStore.PasswordProtection("".toCharArray()));
希望这会帮助你。
旧版警告开始:
Chrome 58将要求证书在主题名称字段中指定它们所适用的主机名;“主题”字段中的值将被忽略。
旧版警告结束
import java.io.FileOutputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.util.Date;
import sun.security.x509.CertAndKeyGen;
import sun.security.x509.X500Name;
public class UseKeyTool {
private static final int keysize = 1024;
private static final String commonName = "www.test.de";
private static final String organizationalUnit = "IT";
private static final String organization = "test";
private static final String city = "test";
private static final String state = "test";
private static final String country = "DE";
private static final long validity = 1096; // 3 years
private static final String alias = "tomcat";
private static final char[] keyPass = "changeit".toCharArray();
// copied most ideas from sun.security.tools.KeyTool.java
@SuppressWarnings("restriction")
public static void main(String[] args) throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);
CertAndKeyGen keypair = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
X500Name x500Name = new X500Name(commonName, organizationalUnit, organization, city, state, country);
keypair.generate(keysize);
PrivateKey privKey = keypair.getPrivateKey();
X509Certificate[] chain = new X509Certificate[1];
chain[0] = keypair.getSelfCertificate(x500Name, new Date(), (long) validity * 24 * 60 * 60);
keyStore.setKeyEntry(alias, privKey, keyPass, chain);
keyStore.store(new FileOutputStream(".keystore"), keyPass);
}
}