英文:
Generating an X509 Certificate in Java
问题
这是生成X509证书的Java代码。首先,我已经使用以下代码生成了公钥和私钥:
public static void generateKeys() {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = SecureRandom.getInstanceStrong();
keyGen.initialize(2048, random);
KeyPair pair = keyGen.generateKeyPair();
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();
byte[] encPriv = priv.getEncoded();
FileOutputStream privfos = new FileOutputStream(PRIVATE_KEY_FILENAME);
privfos.write(encPriv);
privfos.close();
byte[] encPub = pub.getEncoded();
FileOutputStream pubfos = new FileOutputStream(PUBLIC_KEY_FILENAME);
pubfos.write(encPub);
pubfos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
然后,以下是用于生成X509证书的代码:
public static PrivateKey getPrivateKey() throws Exception {
byte[] pkcs8EncodedBytes = Files.readAllBytes(PRIVATE_KEY_FILENAME);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(keySpec);
}
public static PublicKey getPublicKey() throws Exception {
byte[] publicEncodedBytes = Files.readAllBytes(PUBLIC_KEY_FILENAME);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicEncodedBytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return factory.generatePublic(publicKeySpec);
}
public static X509Certificate generateX509Certificate() throws Exception {
PrivateKey privateKey = getPrivateKey();
PublicKey publicKey = getPublicKey();
KeyPair keyPair = new KeyPair(publicKey, privateKey);
final Instant now = Instant.now();
final Date notBefore = Date.from(now);
final Date until = LocalDate.now().plusYears(100).toDate();
final ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WITHRSA").build(keyPair.getPrivate());
final X500Name x500Name = new X500Name("CN=Common Name,O=Organization,L=City,ST=State");
final X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(x500Name,
BigInteger.valueOf(now.toEpochMilli()), notBefore, until, x500Name, keyPair.getPublic());
return new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider())
.getCertificate(certificateBuilder.build(contentSigner));
}
请注意,这些代码看起来是用于生成X509证书的,但我无法保证其完全正确性,因为代码的正确性可能受到许多因素的影响,例如配置和上下文环境。如果您需要确保代码的准确性,建议您在测试环境中进行测试并与安全专家一起审查代码。
英文:
I need to generate a public X509 Certificate but I have very little experience with Security in Java. I just want to make sure that what I am currently doing will work. First, I have already generated a public and private key with the following code:
public static void generateKeys() {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
SecureRandom random = SecureRandom.getInstanceStrong();
keyGen.initialize(2048, random);
KeyPair pair = keyGen.generateKeyPair();
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();
byte[] encPriv = priv.getEncoded();
FileOutputStream privfos = new FileOutputStream(PRIVATE_KEY_FILENAME);
privfos.write(encPriv);
privfos.close();
byte[] encPub = pub.getEncoded();
FileOutputStream pubfos = new FileOutputStream(PUBLIC_KEY_FILENAME);
pubfos.write(encPub);
pubfos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
And here is the code used for generating the X509Certificate:
public static PrivateKey getPrivateKey() throws Exception {
byte[] pkcs8EncodedBytes = Files.readAllBytes(PRIVATE_KEY_FILENAME);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkcs8EncodedBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(keySpec);
}
public static PublicKey getPublicKey() throws Exception {
byte[] publicEncodedBytes = Files.readAllBytes(PUBLIC_KEY_FILENAME);
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicEncodedBytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return factory.generatePublic(publicKeySpec);
}
public static X509Certificate generateX509Certificate() throws Exception {
PrivateKey privateKey = getPrivateKey();
PublicKey publicKey = getPublicKey();
KeyPair keyPair = new KeyPair(publicKey, privateKey);
final Instant now = Instant.now();
final Date notBefore = Date.from(now);
final Date until = LocalDate.now().plusYears(100).toDate();
final ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WITHRSA").build(keyPair.getPrivate());
final X500Name x500Name = new X500Name("CN=Common Name,O=Organization,L=City,ST=State");
final X509v3CertificateBuilder certificateBuilder = new JcaX509v3CertificateBuilder(x500Name,
BigInteger.valueOf(now.toEpochMilli()), notBefore, until, x500Name, keyPair.getPublic());
return new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider())
.getCertificate(certificateBuilder.build(contentSigner));
}
Can someone clarify if this is the correct way to create a X509Certificate in Java? Thanks!
答案1
得分: 3
> 我还没有看到你加载密钥库。你检索私钥/公钥的方法似乎不正确。
一个可工作的示例如下:
public static Certificate generateCertificate(KeyPair keyPair) throws CertificateException, OperatorCreationException
{
X500Name x500Name = new X500Name("CN=***.com, OU=Security&Defense, O=*** Crypto., L=Ottawa, ST=Ontario, C=CA");
SubjectPublicKeyInfo pubKeyInfo = SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
final Date start = new Date();
final Date until = Date.from(LocalDate.now().plus(365, ChronoUnit.DAYS).atStartOfDay().toInstant(ZoneOffset.UTC));
final X509v3CertificateBuilder certificateBuilder = new X509v3CertificateBuilder(x500Name,
new BigInteger(10, new SecureRandom()), start, until, x500Name, pubKeyInfo
);
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(keyPair.getPrivate());
Certificate certificate = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate(certificateBuilder.build(contentSigner));
System.out.println("x.509证书已成功生成!");
return certificate;
}
> 生成证书日志:
在密钥库/security/keystore/Andante-x509.jks中生成证书
使用密码在密钥库中封装KeyPair...
x.509证书已成功生成!
会话结束。
> 从密钥库中提取和验证证书:
>> 如果证书不存在:
证书API异常:系统找不到指定的路径。
>> 如果KeyStore
中的alias
不匹配:
密钥库异常:无法检索密钥。
>> 如果KeyStore
中的password
不匹配:
密钥库异常:密钥库已被篡改,或密码不正确。
英文:
> I haven't seen your loading a Key Store. Your method of retrieving the private/public key doesn't seem right.
A working example looks like this:
public static Certificate generateCertificate(KeyPair keyPair) throws CertificateException, OperatorCreationException
{
X500Name x500Name = new X500Name("CN=***.com, OU=Security&Defense, O=*** Crypto., L=Ottawa, ST=Ontario, C=CA");
SubjectPublicKeyInfo pubKeyInfo = SubjectPublicKeyInfo.getInstance(keyPair.getPublic().getEncoded());
final Date start = new Date();
final Date until = Date.from(LocalDate.now().plus(365, ChronoUnit.DAYS).atStartOfDay().toInstant(ZoneOffset.UTC));
final X509v3CertificateBuilder certificateBuilder = new X509v3CertificateBuilder(x500Name,
new BigInteger(10, new SecureRandom()), start, until, x500Name, pubKeyInfo
);
ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(keyPair.getPrivate());
Certificate certificate = new JcaX509CertificateConverter().setProvider(new BouncyCastleProvider()).getCertificate(certificateBuilder.build(contentSigner));
System.out.println("x.509 certificate is successfully generated!");
return certificate;
}
> Generate certificate logging:
Generating certificate in KeyStore /security/keystore/Andante-x509.jks
Encapsulating KeyPair with password in KeyStore...
x.509 certificate is successfully generated!
Sitzung beendet wird.
> Extract and validate certificate from KeyStore:
>> If certificate doesn’t exist:
Certificate API Exception: The system cannot find the path specified.
>> If KeyStore
alias
doesn’t match:
KeyStore Exception: Key cannot be retrieved.
>> If KeyStore
password
doesn’t match:
KeyStore Exception: Keystore was tampered with, or password was incorrect.
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论