/** * Create a self-signed X.509 Certificate. * From http://bfo.com/blog/2011/03/08/odds_and_ends_creating_a_new_x_509_certificate.html. * * @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB" * @param pair the KeyPair * @param days how many days from now the Certificate is valid for * @param algorithm the signing algorithm, eg "SHA1withRSA" * @return the self-signed certificate * @throws IOException thrown if an IO error ocurred. * @throws GeneralSecurityException thrown if an Security error ocurred. */ public static 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; }
private static X509Certificate generateCert( String hostname, KeyPair kp, boolean isCertAuthority, PublicKey signerPublicKey, PrivateKey signerPrivateKey) throws IOException, CertificateException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { X500Name issuer = new X500Name("CN=root" + issuerDirString); X500Name subject; if (hostname == null) { subject = issuer; } else { subject = new X500Name("CN=" + hostname + issuerDirString); } X509CertInfo info = new X509CertInfo(); Date from = new Date(); Date to = new Date(from.getTime() + 365 * 86400000l); CertificateValidity interval = new CertificateValidity(from, to); BigInteger sn = new BigInteger(64, new SecureRandom()); info.set(X509CertInfo.VALIDITY, interval); info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)); info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(subject)); info.set(X509CertInfo.ISSUER, new CertificateIssuerName(issuer)); info.set(X509CertInfo.KEY, new CertificateX509Key(kp.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(signerPrivateKey, signingAlgorithm); // Update the algorithm, and resign. algo = (AlgorithmId)cert.get(X509CertImpl.SIG_ALG); info.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, algo); cert = new X509CertImpl(info); cert.sign(signerPrivateKey, signingAlgorithm); return cert; }
/** * Create an X509 Certificate signed using SHA1withRSA with a 2048 bit key. * @param dname Domain Name to represent the certificate * @param notBefore The date by which the certificate starts being valid. Cannot be null. * @param validity The number of days the certificate is valid after notBefore. * @return An X509 certificate setup with properties using the specified parameters. * @throws Exception */ public static X509Certificate createCert(String dname, Date notBefore, int validity) throws Exception { int keysize = 2048; String keyAlgName = "RSA"; String sigAlgName = "SHA1withRSA"; if (dname == null) throw new Exception("Required DN is null. Please specify cert Domain Name via dname"); if (notBefore == null) throw new Exception("Required start date is null. Please specify the date at which the cert is valid via notBefore"); if (validity < 0) throw new Exception("Required validity is negative. Please specify the number of days for which the cert is valid after the start date."); // KeyTool#doGenKeyPair X500Name x500Name = new X500Name(dname); KeyPair keyPair = new KeyPair(keyAlgName, sigAlgName, keysize); PrivateKey privKey = keyPair.getPrivateKey(); X509Certificate oldCert = keyPair.getSelfCertificate(x500Name, notBefore, validity); // KeyTool#doSelfCert byte[] encoded = oldCert.getEncoded(); X509CertImpl certImpl = new X509CertImpl(encoded); X509CertInfo certInfo = (X509CertInfo) certImpl.get(X509CertImpl.NAME + "." + X509CertImpl.INFO); Date notAfter = new Date(notBefore.getTime() + validity*1000L*24L*60L*60L); CertificateValidity interval = new CertificateValidity(notBefore, notAfter); certInfo.set(X509CertInfo.VALIDITY, interval); certInfo.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber( new java.util.Random().nextInt() & 0x7fffffff)); certInfo.set(X509CertInfo.SUBJECT + "." + CertificateSubjectName.DN_NAME, x500Name); certInfo.set(X509CertInfo.ISSUER + "." + CertificateIssuerName.DN_NAME, x500Name); // The inner and outer signature algorithms have to match. // The way we achieve that is really ugly, but there seems to be no // other solution: We first sign the cert, then retrieve the // outer sigalg and use it to set the inner sigalg X509CertImpl newCert = new X509CertImpl(certInfo); newCert.sign(privKey, sigAlgName); AlgorithmId sigAlgid = (AlgorithmId)newCert.get(X509CertImpl.SIG_ALG); certInfo.set(CertificateAlgorithmId.NAME + "." + CertificateAlgorithmId.ALGORITHM, sigAlgid); certInfo.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3)); // FIXME Figure out extensions // CertificateExtensions ext = createV3Extensions( // null, // (CertificateExtensions)certInfo.get(X509CertInfo.EXTENSIONS), // v3ext, // oldCert.getPublicKey(), // null); // certInfo.set(X509CertInfo.EXTENSIONS, ext); newCert = new X509CertImpl(certInfo); newCert.sign(privKey, sigAlgName); return newCert; }