简体   繁体   English

在java中生成证书链

[英]Generate certificate chain in java

The question is how to generate certificate chains programmatically in Java. 问题是如何在Java中以编程方式生成证书链。 In other words, I would like to perform in java the operations detailed here: http://fusesource.com/docs/broker/5.3/security/i382664.html 换句话说,我想在java中执行这里详述的操作: http//fusesource.com/docs/broker/5.3/security/i382664.html

Besically, I can create the RSA keys for a new client: 通常,我可以为新客户创建RSA密钥:

private KeyPair genRSAKeyPair(){
    // Get RSA key factory:
    KeyPairGenerator kpg = null;
    try {
        kpg = KeyPairGenerator.getInstance("RSA");
    } catch (NoSuchAlgorithmException e) {
        log.error(e.getMessage());
        e.printStackTrace();
        return null;
    }
    // Generate RSA public/private key pair:
    kpg.initialize(RSA_KEY_LEN);
    KeyPair kp = kpg.genKeyPair();
    return kp;

} }

and I generate the corresponding certificate: 我生成相​​应的证书:

private X509Certificate generateCertificate(String dn, KeyPair pair, int days, String algorithm)
  throws GeneralSecurityException, IOException  {
    PrivateKey privkey = pair.getPrivate();
    X509CertInfo info = new X509CertInfo();
    Date from = new Date();
    Date to = new Date(from.getTime() + days * 86400000l);
    CertificateValidity interval = new CertificateValidity(from, to);
    BigInteger sn = new BigInteger(64, new SecureRandom());
    X500Name owner = new X500Name(dn);

    info.set(X509CertInfo.VALIDITY, interval);
    info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn));
    info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
    info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
    info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic()));
    info.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
    AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid);
    info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo));

    // Sign the cert to identify the algorithm that's used.
    X509CertImpl cert = new X509CertImpl(info);
    cert.sign(privkey, algorithm);

    // Update the algorith, and resign.
    algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG);
    info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo);
    cert = new X509CertImpl(info);
    cert.sign(privkey, algorithm);
    return cert;

} }

Then I generate the cert signing request and I save it to csrFile file: 然后我生成证书签名请求,并将其保存到csrFile文件:

public static void writeCertReq(File csrFile, String alias, String keyPass, KeyStore ks) 
        throws KeyStoreException, 
               NoSuchAlgorithmException, 
               InvalidKeyException, 
               IOException, 
               CertificateException, 
               SignatureException, 
               UnrecoverableKeyException {

    Object objs[] = getPrivateKey(ks, alias, keyPass.toCharArray());
    PrivateKey privKey = (PrivateKey) objs[0];

    PKCS10 request = null;

    Certificate cert = ks.getCertificate(alias);
    request = new PKCS10(cert.getPublicKey());
    String sigAlgName = "MD5WithRSA";
    Signature signature = Signature.getInstance(sigAlgName);
    signature.initSign(privKey);
    X500Name subject = new X500Name(((X509Certificate) cert).getSubjectDN().toString());
    X500Signer signer = new X500Signer(signature, subject);
    request.encodeAndSign(signer);
    request.print(System.out);
    FileOutputStream fos = new FileOutputStream(csrFile);
    PrintStream ps = new PrintStream(fos);
    request.print(ps);
    fos.close();
}

where 哪里

private static Object[] getPrivateKey(KeyStore ks, String alias, char keyPass[]) 
        throws UnrecoverableKeyException, KeyStoreException, NoSuchAlgorithmException {
    key = null;        
    key = ks.getKey(alias, keyPass);
    return (new Object[]{ (PrivateKey) key, keyPass });
}

Now I should sign the CSR with the CA private key, but I cannot see how to achive that in java. 现在我应该使用CA私钥对CSR进行签名,但是我无法看到如何在java中实现这一点。 I have "my own" CA private key in my jks. 我的jks中有“我自己的”CA私钥。

Besides, once I manage to sign the CSR I should chain the CA cert with the signed CSR: how that can be done in java? 此外,一旦我设法签署CSR,我应该使用签名的CSR链接CA证书:如何在java中完成?

I would prefer not to use bc or other external libs, just "sun.security" classes. 我宁愿不使用bc或其他外部库,只是“sun.security”类。

Thank you. 谢谢。

I believe the code example in the post http://www.pixelstech.net/article/1406726666-Generate-certificate-in-Java----2 will show you how to generate certificate chain with pure Java. 我相信http://www.pixelstech.net/article/1406726666-Generate-certificate-in-Java----2中的代码示例将向您展示如何使用纯Java生成证书链。 It doesn't require you to use Bouncy Castle. 它不要求你使用Bouncy Castle。

Sorry, but despite your desires, and besides writing all of your crypto code and including it with your project (not recommended), I'd recommend using Bouncy Castle here. 抱歉,尽管你有自己的愿望,除了编写你的所有加密代码并将其包含在你的项目中(不推荐),我建议你在这里使用Bouncy Castle。

Specifically, please refer to https://stackoverflow.com/a/7366757/751158 - which includes code for exactly what you're looking to do. 具体来说,请参阅https://stackoverflow.com/a/7366757/751158 - 其中包含您正在寻找的确切代码。

I see you've already gone over to the BouncyCastle side of the house but just in case anyone else was wondering; 我看到你已经到了房子的BouncyCastle那边,但以防其他人在想; you can add the cert chain to the entry when putting the key into the KeyStore. 将密钥放入KeyStore时,可以将证书链添加到条目中。 For example 例如

// build your certs 

KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load([keystore stream], password.toCharArray());// or null, null if it's a brand new store
X509Certificate[] chain = new X509Certificate[2];
chain[0] = _clientCert;
chain[1] = _caCert;
keyStore.setKeyEntry("Alias", _clientCertKey, password.toCharArray(), chain);
keyStore.store([output stream], password.toCharArray());

// do other stuff

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM