在Java中生成X509证书
我需要生成一个公共X509证书,但我对Java的安全性几乎没有经验。我只是想确保我目前所做的一切都能奏效。首先,我已经使用以下代码生成了公钥和私钥:在Java中生成X509证书,java,digital-signature,Java,Digital Signature,我需要生成一个公共X509证书,但我对Java的安全性几乎没有经验。我只是想确保我目前所做的一切都能奏效。首先,我已经使用以下代码生成了公钥和私钥: public static void generateKeys() { try { KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); SecureRandom random = Secure
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));
}
有人能澄清一下这是否是用Java创建X509证书的正确方法吗?谢谢
我还没看到你在钥匙店装钥匙。您检索私钥/公钥的方法似乎不正确。工作示例如下所示: 生成证书日志记录: 从密钥库提取并验证证书: 如果证书不存在: 如果
密钥库
别名
不匹配:
如果密钥库
密码
不匹配:
虽然密钥存储库(有意地)在大多数情况下适合并方便存储密钥,但它不是唯一的方法;Q中的write(key.getEncoded())和readAllBytes+KeyFactory方法有效——尽管将未加密的私钥保存在文件中通常是不安全的。是的,Java安全结构的主要功能是为证书提供准确性和有效性。如果黑客截取或替换数据、密钥对或签名,编码的密钥将变得无用。证书在密钥库中加密后,
别名
允许存在真正的证书。虽然加密
不允许篡改密钥库…这是我的理解…替换公钥和泄露私钥是不同的威胁(但两者都很重要)。私钥在基于文件的密钥库(JKS、JCEKS、PKCS12)中加密,并在其他密钥库(如PKCS11/HSM)中具有同等的保护;证书不需要加密,通常也不加密,但受到完整性措施的保护,如基于文件的存储上的PBMAC。我在应答
中添加了提取
输出。。。基于提取
和验证逻辑,什么可以更好地保护证书?我洗耳恭听。我不知道你在问什么。如果您在通常的基于文件的Java密钥库中拥有证书,那么(PB)MAC会保护它不被替换(或更改);别名有助于组织密钥库,但不保护密钥库(攻击者可以很容易地枚举别名,即使在PKCS12中也是如此)。对于某些格式,证书是不加密的,因此不受暴露的保护,但这不是问题,因为证书(通常是公钥)被定义为公共的。OTOH私钥总是加密的(也包括在MAC中)。Neardupe
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;
}
Generating certificate in KeyStore /security/keystore/Andante-x509.jks
Encapsulating KeyPair with password in KeyStore...
x.509 certificate is successfully generated!
Sitzung beendet wird.
Certificate API Exception: The system cannot find the path specified.
KeyStore Exception: Key cannot be retrieved.
KeyStore Exception: Keystore was tampered with, or password was incorrect.