如何生成密钥对并以编程方式将其插入 KeyStore(不使用 Java KeyTool)?
How can I generate a key pair and insert it into a KeyStore programmatically (without using the Java KeyTool)?
我想生成一个密钥对并以编程方式将其插入 Java KeyStore。我可以使用命令行来做我想做的事情,但是如何使用 Java 代码来做呢?
命令行如下:
keytool -genkeypair \
-dname "cn=Unknown" \
-alias main \
-keyalg RSA \
-keysize 4096 \
-keypass 654321 \
-keystore C:\Users\Felipe\ks \
-storepass 123456 \
-validity 365
这是我目前的 Java 代码:
public static void main(String[] args) {
try (
FileOutputStream fos = new FileOutputStream("C:\Users\Felipe\ks");
) {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096, SecureRandom.getInstance("SHA1PRNG"));
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Certificate[] chain = {};
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setKeyEntry("main", keyPair.getPrivate(), "654321".toCharArray(), chain); // Error: Private key must be accompanied by certificate chain
keyStore.store(fos, "123456".toCharArray());
} catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) {
e.printStackTrace();
}
}
但我不断收到以下错误消息:Private key must be accompanied by certificate chain
。
我想我应该创建一个证书并将其插入证书数组,但是该怎么做?
这是一个很好的 Java 函数,用于以编程方式生成自签名证书 (link):
private X509Certificate generateCertificate(String dn, KeyPair keyPair, int validity, String sigAlgName) throws GeneralSecurityException, IOException {
PrivateKey privateKey = keyPair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date();
Date to = new Date(from.getTime() + validity * 1000L * 24L * 60L * 60L);
CertificateValidity interval = new CertificateValidity(from, to);
BigInteger serialNumber = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn);
AlgorithmId sigAlgId = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(serialNumber));
info.set(X509CertInfo.SUBJECT, owner);
info.set(X509CertInfo.ISSUER, owner);
info.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(sigAlgId));
// Sign the cert to identify the algorithm that's used.
X509CertImpl certificate = new X509CertImpl(info);
certificate.sign(privateKey, sigAlgName);
// Update the algorith, and resign.
sigAlgId = (AlgorithmId) certificate.get(X509CertImpl.SIG_ALG);
info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, sigAlgId);
certificate = new X509CertImpl(info);
certificate.sign(privateKey, sigAlgName);
return certificate;
}
您可以使用它从您的密钥对生成证书并将其插入证书链,以使 setKeyEntry()
方法起作用:
public static void main(String[] args) {
try (
FileOutputStream fos = new FileOutputStream("C:\Users\Felipe\ks");
) {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Certificate[] chain = {generateCertificate("cn=Unknown", keyPair, 365, "SHA256withRSA")};
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setKeyEntry("main", keyPair.getPrivate(), "654321".toCharArray(), chain);
keyStore.store(fos, "123456".toCharArray());
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
}
}
我想生成一个密钥对并以编程方式将其插入 Java KeyStore。我可以使用命令行来做我想做的事情,但是如何使用 Java 代码来做呢?
命令行如下:
keytool -genkeypair \
-dname "cn=Unknown" \
-alias main \
-keyalg RSA \
-keysize 4096 \
-keypass 654321 \
-keystore C:\Users\Felipe\ks \
-storepass 123456 \
-validity 365
这是我目前的 Java 代码:
public static void main(String[] args) {
try (
FileOutputStream fos = new FileOutputStream("C:\Users\Felipe\ks");
) {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096, SecureRandom.getInstance("SHA1PRNG"));
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Certificate[] chain = {};
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setKeyEntry("main", keyPair.getPrivate(), "654321".toCharArray(), chain); // Error: Private key must be accompanied by certificate chain
keyStore.store(fos, "123456".toCharArray());
} catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException e) {
e.printStackTrace();
}
}
但我不断收到以下错误消息:Private key must be accompanied by certificate chain
。
我想我应该创建一个证书并将其插入证书数组,但是该怎么做?
这是一个很好的 Java 函数,用于以编程方式生成自签名证书 (link):
private X509Certificate generateCertificate(String dn, KeyPair keyPair, int validity, String sigAlgName) throws GeneralSecurityException, IOException {
PrivateKey privateKey = keyPair.getPrivate();
X509CertInfo info = new X509CertInfo();
Date from = new Date();
Date to = new Date(from.getTime() + validity * 1000L * 24L * 60L * 60L);
CertificateValidity interval = new CertificateValidity(from, to);
BigInteger serialNumber = new BigInteger(64, new SecureRandom());
X500Name owner = new X500Name(dn);
AlgorithmId sigAlgId = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
info.set(X509CertInfo.VALIDITY, interval);
info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(serialNumber));
info.set(X509CertInfo.SUBJECT, owner);
info.set(X509CertInfo.ISSUER, owner);
info.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(sigAlgId));
// Sign the cert to identify the algorithm that's used.
X509CertImpl certificate = new X509CertImpl(info);
certificate.sign(privateKey, sigAlgName);
// Update the algorith, and resign.
sigAlgId = (AlgorithmId) certificate.get(X509CertImpl.SIG_ALG);
info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, sigAlgId);
certificate = new X509CertImpl(info);
certificate.sign(privateKey, sigAlgName);
return certificate;
}
您可以使用它从您的密钥对生成证书并将其插入证书链,以使 setKeyEntry()
方法起作用:
public static void main(String[] args) {
try (
FileOutputStream fos = new FileOutputStream("C:\Users\Felipe\ks");
) {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(4096);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Certificate[] chain = {generateCertificate("cn=Unknown", keyPair, 365, "SHA256withRSA")};
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setKeyEntry("main", keyPair.getPrivate(), "654321".toCharArray(), chain);
keyStore.store(fos, "123456".toCharArray());
} catch (IOException | GeneralSecurityException e) {
e.printStackTrace();
}
}