CreateCert.java
package com.secpki.jce.demo; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Security; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.security.spec.RSAPrivateCrtKeySpec; import java.security.spec.RSAPublicKeySpec; import java.util.Date; import java.util.Hashtable; import java.util.Random; import java.util.Vector; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.DERBitString; import org.bouncycastle.asn1.DERBoolean; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERGeneralizedTime; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERPrintableString; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERSet; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.DERUTCTime; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.AccessDescription; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x509.Attribute; import org.bouncycastle.asn1.x509.CRLDistPoint; import org.bouncycastle.asn1.x509.DistributionPoint; import org.bouncycastle.asn1.x509.DistributionPointName; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralNames; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.bouncycastle.asn1.x509.KeyUsage; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.PolicyMappings; import org.bouncycastle.asn1.x509.PrivateKeyUsagePeriod; import org.bouncycastle.asn1.x509.SubjectDirectoryAttributes; import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; import org.bouncycastle.asn1.x509.V3TBSCertificateGenerator; import org.bouncycastle.asn1.x509.X509CertificateStructure; import org.bouncycastle.asn1.x509.X509Extensions; import org.bouncycastle.asn1.x509.X509ExtensionsGenerator; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.X509CertificateObject; public class CreateCert { public BigInteger genCertSerial() { // BigInteger bigInteger = new BigInteger(val); byte[] b = new byte[32]; Random random = new Random(new Date().getTime()); for (int i = 0; i < 32; i++) { byte[] tmp = new byte[10]; random.nextBytes(tmp); b[i] = tmp[random.nextInt(tmp.length - 1)]; } return new BigInteger(b); } public X509Certificate createAcIssuerCert(X500Name issuer, BigInteger serial, Date notBefore, Date notAfter, X500Name subject, final SubjectPublicKeyInfo publicKeyInfo, PrivateKey privKey) throws Exception { V3TBSCertificateGenerator certificateGenerator = new V3TBSCertificateGenerator(); certificateGenerator.setExtensions(getCertGen()); certificateGenerator.setSignature(publicKeyInfo.getAlgorithmId()); certificateGenerator.setIssuer(issuer); certificateGenerator.setSubject(subject); certificateGenerator.setSerialNumber(new DERInteger(serial)); certificateGenerator.setStartDate(new DERUTCTime(notBefore)); certificateGenerator.setEndDate(new DERUTCTime(notAfter)); certificateGenerator.setSubjectPublicKeyInfo(publicKeyInfo); System.out.println(certificateGenerator.generateTBSCertificate() .getEncoded().length); ASN1EncodableVector asn1encodablevector = new ASN1EncodableVector(); asn1encodablevector.add(certificateGenerator.generateTBSCertificate()); asn1encodablevector.add(publicKeyInfo.getAlgorithmId()); byte[] pubData = new byte[65]; pubData[0] = 0; for(byte i=1;i<pubData.length;i++){ pubData[i] = i; } byte[] signInfo = new byte[69];//..... for(byte i=1;i<pubData.length;i++){ pubData[i] = i; } asn1encodablevector.add(new DERBitString(signInfo)); X509CertificateObject cert = new X509CertificateObject(new X509CertificateStructure(new DERSequence(asn1encodablevector))); return cert; } @SuppressWarnings("deprecation") static X509Extensions getCertGen() { // 添加扩展 X509ExtensionsGenerator certGen = new X509ExtensionsGenerator(); // 基本限制 certGen.addExtension(X509Extensions.BasicConstraints, false, new DEREncodable() { @Override public DERObject getDERObject() { // TODO Auto-generated method stub ASN1EncodableVector bConstraints = new ASN1EncodableVector(); // 是否是CA证书 boolean bCA = false; bConstraints.add(new DERBoolean(bCA)); // 证书路径长度限制 int pathLenConstraint = 3; if ((pathLenConstraint >= 0) && (bCA)) bConstraints.add(new DERInteger(pathLenConstraint)); return new DERSequence(bConstraints); } }); // 密钥用法 certGen.addExtension(X509Extensions.KeyUsage, false, new DEREncodable() { @SuppressWarnings("unused") public int keyUsage; public static final int digitalSignature = (1 << 7); public static final int nonRepudiation = (1 << 6); public static final int keyEncipherment = (1 << 5); public static final int dataEncipherment = (1 << 4); public static final int keyAgreement = (1 << 3); public static final int keyCertSign = (1 << 2); public static final int cRLSign = (1 << 1); public static final int encipherOnly = (1 << 0); public static final int decipherOnly = (1 << 15); @Override public DERObject getDERObject() { // TODO Auto-generated method stub return new KeyUsage(digitalSignature | nonRepudiation | keyEncipherment | dataEncipherment | keyAgreement | keyCertSign | cRLSign | encipherOnly | decipherOnly); } }); // 扩展密钥用法 certGen.addExtension(X509Extensions.ExtendedKeyUsage, false, new DEREncodable() { private static final String id_kp = "1.3.6.1.5.5.7.3"; @SuppressWarnings("unused") public final KeyPurposeId anyExtendedKeyUsage = new KeyPurposeId( X509Extensions.ExtendedKeyUsage.getId() + ".0"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_serverAuth = new KeyPurposeId( id_kp + ".1"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_clientAuth = new KeyPurposeId( id_kp + ".2"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_codeSigning = new KeyPurposeId( id_kp + ".3"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_emailProtection = new KeyPurposeId( id_kp + ".4"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_ipsecEndSystem = new KeyPurposeId( id_kp + ".5"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_ipsecTunnel = new KeyPurposeId( id_kp + ".6"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_ipsecUser = new KeyPurposeId( id_kp + ".7"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_timeStamping = new KeyPurposeId( id_kp + ".8"); public final KeyPurposeId id_kp_OCSPSigning = new KeyPurposeId( id_kp + ".9"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_dvcs = new KeyPurposeId( id_kp + ".10"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_sbgpCertAAServerAuth = new KeyPurposeId( id_kp + ".11"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_scvp_responder = new KeyPurposeId( id_kp + ".12"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_eapOverPPP = new KeyPurposeId( id_kp + ".13"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_eapOverLAN = new KeyPurposeId( id_kp + ".14"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_scvpServer = new KeyPurposeId( id_kp + ".15"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_scvpClient = new KeyPurposeId( id_kp + ".16"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_ipsecIKE = new KeyPurposeId( id_kp + ".17"); public final KeyPurposeId id_kp_capwapAC = new KeyPurposeId( id_kp + ".18"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_capwapWTP = new KeyPurposeId( id_kp + ".19"); @SuppressWarnings("unused") public final KeyPurposeId id_kp_smartcardlogon = new KeyPurposeId( "1.3.6.1.4.1.311.20.2.2"); ASN1EncodableVector extKeyUsage = new ASN1EncodableVector(); @Override public DERObject getDERObject() { // TODO Auto-generated method stub extKeyUsage.add(id_kp_OCSPSigning); extKeyUsage.add(id_kp_capwapAC); return new DERSequence(extKeyUsage); } }); // 主题备用名称 certGen.addExtension(X509Extensions.SubjectAlternativeName, false, new DEREncodable() { @SuppressWarnings("unused") public static final int otherName = 0; @SuppressWarnings("unused") public static final int rfc822Name = 1; @SuppressWarnings("unused") public static final int dNSName = 2; @SuppressWarnings("unused") public static final int x400Address = 3; @SuppressWarnings("unused") public static final int directoryName = 4; @SuppressWarnings("unused") public static final int ediPartyName = 5; @SuppressWarnings("unused") public static final int uniformResourceIdentifier = 6; public static final int iPAddress = 7; @SuppressWarnings("unused") public static final int registeredID = 8; @Override public DERObject getDERObject() { // TODO Auto-generated method stub ASN1EncodableVector nameVector = new ASN1EncodableVector(); nameVector.add(new GeneralName(iPAddress, "127.0.0.1")); return new GeneralNames(new DERSequence(nameVector)) .getDERObject(); } }); // 颁发者备用别名 certGen.addExtension(X509Extensions.IssuerAlternativeName, false, new DEREncodable() { @SuppressWarnings("unused") public static final int otherName = 0; @SuppressWarnings("unused") public static final int rfc822Name = 1; @SuppressWarnings("unused") public static final int dNSName = 2; @SuppressWarnings("unused") public static final int x400Address = 3; @SuppressWarnings("unused") public static final int directoryName = 4; @SuppressWarnings("unused") public static final int ediPartyName = 5; @SuppressWarnings("unused") public static final int uniformResourceIdentifier = 6; public static final int iPAddress = 7; @SuppressWarnings("unused") public static final int registeredID = 8; @Override public DERObject getDERObject() { // TODO Auto-generated method stub ASN1EncodableVector nameVector = new ASN1EncodableVector(); nameVector.add(new GeneralName(iPAddress, "127.0.0.1")); return new GeneralNames(new DERSequence(nameVector)) .getDERObject(); } }); // 秘钥有效期 certGen.addExtension(X509Extensions.PrivateKeyUsagePeriod, false, new DEREncodable() { @Override public DERObject getDERObject() { // TODO Auto-generated method stub Date notBefore = new Date(); Date notAfter = new Date(notBefore.getTime() * 2); DERGeneralizedTime keyNotBefore = new DERGeneralizedTime( notBefore); DERGeneralizedTime keyNotAfter = new DERGeneralizedTime( notAfter); DERTaggedObject atokeyNotBefore = new DERTaggedObject( false, 0, keyNotBefore); DERTaggedObject atokeyNotAfter = new DERTaggedObject( false, 1, keyNotAfter); ASN1EncodableVector periodVector = new ASN1EncodableVector(); periodVector.add(atokeyNotBefore); periodVector.add(atokeyNotAfter); return PrivateKeyUsagePeriod.getInstance( new DERSequence(periodVector)).getDERObject(); } }); // 策略限制 certGen.addExtension(X509Extensions.PolicyConstraints, false, new DEREncodable() { int requireExplicitPolicy = -1; int inhibitPolicyMapping = -1; @Override public DERObject getDERObject() { // TODO Auto-generated method stub ASN1EncodableVector pConstraints = new ASN1EncodableVector(); if (requireExplicitPolicy >= 0) pConstraints.add(new DERTaggedObject(false, 0, new DERInteger(requireExplicitPolicy))); if (inhibitPolicyMapping >= 0) pConstraints.add(new DERTaggedObject(false, 1, new DERInteger(inhibitPolicyMapping))); return new DERSequence(pConstraints); } }); // 禁止任意策略 certGen.addExtension(X509Extensions.InhibitAnyPolicy, false, new DEREncodable() { public int InhibitAnyPolicy; @Override public DERObject getDERObject() { // TODO Auto-generated method stub if (InhibitAnyPolicy >= 0) return new DERInteger(InhibitAnyPolicy); else return null; } }); // 证书策略 certGen.addExtension(X509Extensions.CertificatePolicies, false, new CertificatePoliciesInfo()); // 策略映射 certGen.addExtension(X509Extensions.PolicyMappings, false, new DEREncodable() { public Hashtable<String, String> policyMappings = new Hashtable<String, String>(); @Override public DERObject getDERObject() { return new PolicyMappings(policyMappings) .getDERObject(); } @SuppressWarnings("unused") public void add(String policyOID, String mappingPolicyOID) { policyMappings.put(policyOID, mappingPolicyOID); } }); // 主题密钥标识符 /* * certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false, new * DEREncodable() { //TODO public需要设置 public PublicKey keyIdentifier; * * @Override public DERObject getDERObject() { // TODO Auto-generated * method stub return new * SubjectKeyIdentifierStructure(keyIdentifier).getDERObject(); } * * }); */ // 权威密钥标识符 // TODO 请参考RFC3093实现 /* * certGen.addExtension(X509Extensions.AuthorityKeyIdentifier, false, * new DEREncodable() { * * public PublicKey keyIdentifier; //public ExtensionGeneralName * authorityCertIssuer; public BigInteger authorityCertSerialNumber; * * @Override public DERObject getDERObject() { // TODO Auto-generated * method stub ASN1EncodableVector apkInfo = new ASN1EncodableVector(); * SubjectPublicKeyInfo apki; try { if (keyIdentifier != null) { apki = * new SubjectPublicKeyInfo( (ASN1Sequence) new ASN1InputStream( new * ByteArrayInputStream( keyIdentifier .getEncoded())) .readObject()); * Digest digest = new SHA1Digest(); byte[] resBuf = new * byte[digest.getDigestSize()]; byte[] bytes = apki.getPublicKeyData() * .getBytes(); digest.update(bytes, 0, bytes.length); * digest.doFinal(resBuf, 0); apkInfo.add(new DERTaggedObject(false, 0, * new DEROctetString(resBuf))); } if (authorityCertIssuer != null) * apkInfo.add(new DERTaggedObject(false, 1, new GeneralNames(new * GeneralName( authorityCertIssuer.nameType, * authorityCertIssuer.value)))); if (authorityCertSerialNumber != null) * apkInfo.add(new DERTaggedObject(false, 2, new DERInteger( * authorityCertSerialNumber))); return new DERSequence(apkInfo); } * catch (IOException e) { // TODO Auto-generated catch block * e.printStackTrace(); } * * return null; } * * }); */ // 主体目录属性 certGen.addExtension(X509Extensions.SubjectDirectoryAttributes, false, new DEREncodable() { public String gender; public String dateOfBirth; public String streetAddress; public String telephoneNumber; public String mobileTelephoneNumber; @Override public DERObject getDERObject() { String genderOid = "1.3.6.1.5.5.7.9.4"; String dateOfBirthOid = "1.3.6.1.5.5.7.9.1"; String streetAddressOid = "2.5.4.9"; String telephoneNumberOid = "2.5.4.20"; String mobileTelephoneNumberOid = "0.9.2342.19200300.100.1.41"; Vector<Attribute> attributes = new Vector<Attribute>(); try { if (gender != null) attributes .add(makeAttribute(genderOid, gender)); if (dateOfBirth != null) attributes.add(makeAttribute(dateOfBirthOid, dateOfBirth)); if (streetAddress != null) attributes.add(makeAttribute(streetAddressOid, streetAddress)); if (telephoneNumber != null) attributes.add(makeAttribute( telephoneNumberOid, telephoneNumber)); if (mobileTelephoneNumber != null) attributes.add(makeAttribute( mobileTelephoneNumberOid, mobileTelephoneNumber)); return new SubjectDirectoryAttributes(attributes) .getDERObject(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } private Attribute makeAttribute(String oid, String value) throws UnsupportedEncodingException { DERSet valueSet = new DERSet(new DERPrintableString( value.getBytes("UTF-8"))); return new Attribute(new DERObjectIdentifier(oid), valueSet); } }); // 名称限制 certGen.addExtension(X509Extensions.NameConstraints, false, new DEREncodable() { private Vector<GeneralSubtree> permittedSubtrees = new Vector<GeneralSubtree>(); private Vector<GeneralSubtree> excludedSubtrees = new Vector<GeneralSubtree>(); @Override public DERObject getDERObject() { // TODO Auto-generated method stub return new NameConstraints(permittedSubtrees, excludedSubtrees).getDERObject(); } @SuppressWarnings("unused") public void addPermitted( ExtensionGeneralName permittedName, int minimum, int maximum) { permittedSubtrees.add(new GeneralSubtree( new GeneralName(permittedName.nameType, permittedName.value), BigInteger .valueOf(minimum), BigInteger .valueOf(maximum))); } @SuppressWarnings("unused") public void addExcluded(ExtensionGeneralName excludedName, int minimum, int maximum) { excludedSubtrees.add(new GeneralSubtree( new GeneralName(excludedName.nameType, excludedName.value), BigInteger .valueOf(minimum), BigInteger .valueOf(maximum))); } }); // CRL分布点 certGen.addExtension(X509Extensions.CRLDistributionPoints, false, new DEREncodable() { private Vector<ExtensionGeneralName> crlDistPoints = new Vector<ExtensionGeneralName>(); @Override public DERObject getDERObject() { // TODO Auto-generated method stub int iCount = crlDistPoints.size(); assert (iCount > 0); DistributionPoint[] dp = new DistributionPoint[iCount]; for (int i = 0; i < iCount; ++i) { DistributionPointName dpn = new DistributionPointName( new GeneralNames( new GeneralName( crlDistPoints.elementAt(i).nameType, crlDistPoints.elementAt(i).value))); dp[i] = new DistributionPoint(dpn, null, null); } return new CRLDistPoint(dp).getDERObject(); } @SuppressWarnings("unused") public void add(ExtensionGeneralName info) { crlDistPoints.add(info); } }); // 最新/增量CRL分布点 certGen.addExtension(X509Extensions.FreshestCRL, false, new DEREncodable() { private Vector<ExtensionGeneralName> crlDistPoints = new Vector<ExtensionGeneralName>(); @Override public DERObject getDERObject() { // TODO Auto-generated method stub int iCount = crlDistPoints.size(); assert (iCount > 0); DistributionPoint[] dp = new DistributionPoint[iCount]; for (int i = 0; i < iCount; ++i) { DistributionPointName dpn = new DistributionPointName( new GeneralNames( new GeneralName( crlDistPoints.elementAt(i).nameType, crlDistPoints.elementAt(i).value))); dp[i] = new DistributionPoint(dpn, null, null); } return new CRLDistPoint(dp).getDERObject(); } @SuppressWarnings("unused") public void add(ExtensionGeneralName info) { crlDistPoints.add(info); } }); // 机构信息访问 certGen.addExtension(X509Extensions.AuthorityInfoAccess, false, new DEREncodable() { public final DERObjectIdentifier id_ad_caIssuers = new DERObjectIdentifier( "1.3.6.1.5.5.7.48.2"); public final DERObjectIdentifier id_ad_ocsp = new DERObjectIdentifier( "1.3.6.1.5.5.7.48.1"); private ASN1EncodableVector authorityInfoAccessVec = new ASN1EncodableVector(); @Override public DERObject getDERObject() { // TODO Auto-generated method stub return new DERSequence(authorityInfoAccessVec); } @SuppressWarnings("unused") public void add(DERObjectIdentifier accessMethod, ExtensionGeneralName accessLocation) { authorityInfoAccessVec.add(new AccessDescription( accessMethod, new GeneralName( accessLocation.nameType, accessLocation.value))); } @SuppressWarnings("unused") public void add(String accessMethod, ExtensionGeneralName accessLocation) { DERObjectIdentifier am = null; if (accessMethod.equalsIgnoreCase("caIssuers")) am = id_ad_caIssuers; else if (accessMethod.equalsIgnoreCase("ocsp")) am = id_ad_ocsp; else { System.out .println("InfoAccessInfo:no supported type!"); assert (false); } authorityInfoAccessVec.add(new AccessDescription(am, new GeneralName(accessLocation.nameType, accessLocation.value))); } }); // 主题信息访问 /* * certGen.addExtension(X509Extensions.AuthorityInfoAccess, false, new * DEREncodable() { public final DERObjectIdentifier id_ad_caIssuers = * new DERObjectIdentifier( "1.3.6.1.5.5.7.48.2"); public final * DERObjectIdentifier id_ad_ocsp = new DERObjectIdentifier( * "1.3.6.1.5.5.7.48.1"); private ASN1EncodableVector * authorityInfoAccessVec = new ASN1EncodableVector(); * * @Override public DERObject getDERObject() { // TODO Auto-generated * method stub return new DERSequence(authorityInfoAccessVec); } * * @SuppressWarnings("unused") public void add(DERObjectIdentifier * accessMethod, ExtensionGeneralName accessLocation) { * authorityInfoAccessVec.add(new AccessDescription( accessMethod, new * GeneralName( accessLocation.nameType, accessLocation.value))); } * * @SuppressWarnings("unused") public void add(String accessMethod, * ExtensionGeneralName accessLocation) { DERObjectIdentifier am = null; * if (accessMethod.equalsIgnoreCase("caIssuers")) am = id_ad_caIssuers; * else if (accessMethod.equalsIgnoreCase("ocsp")) am = id_ad_ocsp; else * { System.out .println("InfoAccessInfo:no supported type!"); assert * (false); } authorityInfoAccessVec.add(new AccessDescription(am, new * GeneralName(accessLocation.nameType, accessLocation.value))); } }); */ return certGen.generate(); } public static void main(String args[]) throws Exception { Security.addProvider(new BouncyCastleProvider()); X500Name issuer = new X500Name("O=IBM,OU=CSC,CN=dev"); X500Name subject = new X500Name("O=IBM,OU=CSC,CN=ligson"); CreateCert cert = new CreateCert(); BigInteger serail = cert.genCertSerial(); RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec( new BigInteger( "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16)); RSAPrivateCrtKeySpec privKeySpec = new RSAPrivateCrtKeySpec( new BigInteger( "b4a7e46170574f16a97082b22be58b6a2a629798419be12872a4bdba626cfae9900f76abfb12139dce5de56564fab2b6543165a040c606887420e33d91ed7ed7", 16), new BigInteger("11", 16), new BigInteger( "9f66f6b05410cd503b2709e88115d55daced94d1a34d4e32bf824d0dde6028ae79c5f07b580f5dce240d7111f7ddb130a7945cd7d957d1920994da389f490c89", 16), new BigInteger( "c0a0758cdf14256f78d4708c86becdead1b50ad4ad6c5c703e2168fbf37884cb", 16), new BigInteger( "f01734d7960ea60070f1b06f2bb81bfac48ff192ae18451d5e56c734a5aab8a5", 16), new BigInteger( "b54bb9edff22051d9ee60f9351a48591b6500a319429c069a3e335a1d6171391", 16), new BigInteger( "d3d83daf2a0cecd3367ae6f8ae1aeb82e9ac2f816c6fc483533d8297dd7884cd", 16), new BigInteger( "b8f52fc6f38593dabb661d3f50f8897f8106eee68b1bce78a95b132b4e5b5d19", 16)); KeyFactory fact = KeyFactory.getInstance("RSA", "BC"); PublicKey pkKey = fact.generatePublic(pubKeySpec); PrivateKey privateKey = fact.generatePrivate(privKeySpec); System.out.println(pkKey); AlgorithmIdentifier algorithmIdentifier = AlgorithmIdentifier .getInstance(X509Util.getAlgorithmOID("SHA1WITHRSA")); SubjectPublicKeyInfo subjectPublicKeyInfo = new SubjectPublicKeyInfo( algorithmIdentifier, pkKey.getEncoded()); X509Certificate certificate = cert.createAcIssuerCert(issuer, serail, new Date(), new Date(new Date().getTime() + 10000000), subject, subjectPublicKeyInfo, privateKey); // certificate.getEncoded(); FileOutputStream fileOutputStream = new FileOutputStream(new File( "E:/code/itrusca/SecPKI/cert/2.cer")); fileOutputStream.write(certificate.getEncoded()); fileOutputStream.close(); } }
ExtensionGeneralName.java
package com.secpki.jce.demo; public class ExtensionGeneralName{ public int nameType; public String value; public static final int otherName = 0; public static final int rfc822Name = 1; public static final int dNSName = 2; public static final int x400Address = 3; public static final int directoryName = 4; public static final int ediPartyName = 5; public static final int uniformResourceIdentifier = 6; public static final int iPAddress = 7; public static final int registeredID = 8; public static final String[] typeTable = new String[9]; public ExtensionGeneralName() { } public ExtensionGeneralName(int nameType,String value) { this.nameType = nameType; this.value = value; } public void setNameType(int nameType) { this.nameType = nameType; } public void setNameType(String nameType) { if(nameType.equalsIgnoreCase("otherName")) this.nameType = otherName; else if(nameType.equalsIgnoreCase("rfc822Name")) this.nameType = rfc822Name; else if(nameType.equalsIgnoreCase("dNSName")) this.nameType = dNSName; else if(nameType.equalsIgnoreCase("x400Address")) this.nameType = x400Address; else if(nameType.equalsIgnoreCase("directoryName")) this.nameType = directoryName; else if(nameType.equalsIgnoreCase("ediPartyName")) this.nameType = ediPartyName; else if(nameType.equalsIgnoreCase("uniformResourceIdentifier")) this.nameType = uniformResourceIdentifier; else if(nameType.equalsIgnoreCase("iPAddress")) this.nameType = iPAddress; else if(nameType.equalsIgnoreCase("registeredID")) this.nameType = registeredID; else { System.out.println("ExtensionGeneralName:no supported type!"); assert(false); } } }
X509Util.java
package com.secpki.jce.demo; import java.io.IOException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.security.Signature; import java.security.SignatureException; import java.util.ArrayList; import java.util.Enumeration; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.security.auth.x500.X500Principal; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERNull; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.cryptopro.CryptoProObjectIdentifiers; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.oiw.OIWObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.RSASSAPSSparams; import org.bouncycastle.asn1.teletrust.TeleTrusTObjectIdentifiers; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; import org.bouncycastle.jce.X509Principal; import org.bouncycastle.util.Strings; @SuppressWarnings("unchecked") class X509Util { @SuppressWarnings("rawtypes") public static Hashtable algorithms = new Hashtable(); @SuppressWarnings("rawtypes") private static Hashtable params = new Hashtable(); @SuppressWarnings("rawtypes") private static Set noParams = new HashSet(); static { algorithms.put("MD2WITHRSAENCRYPTION", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD2WITHRSA", PKCSObjectIdentifiers.md2WithRSAEncryption); algorithms.put("MD5WITHRSAENCRYPTION", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("MD5WITHRSA", PKCSObjectIdentifiers.md5WithRSAEncryption); algorithms.put("SHA1WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA1WITHRSA", PKCSObjectIdentifiers.sha1WithRSAEncryption); algorithms.put("SHA224WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA224WITHRSA", PKCSObjectIdentifiers.sha224WithRSAEncryption); algorithms.put("SHA256WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA256WITHRSA", PKCSObjectIdentifiers.sha256WithRSAEncryption); algorithms.put("SHA384WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA384WITHRSA", PKCSObjectIdentifiers.sha384WithRSAEncryption); algorithms.put("SHA512WITHRSAENCRYPTION", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA512WITHRSA", PKCSObjectIdentifiers.sha512WithRSAEncryption); algorithms.put("SHA1WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA224WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA256WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA384WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("SHA512WITHRSAANDMGF1", PKCSObjectIdentifiers.id_RSASSA_PSS); algorithms.put("RIPEMD160WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD160WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd160); algorithms.put("RIPEMD128WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD128WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd128); algorithms.put("RIPEMD256WITHRSAENCRYPTION", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("RIPEMD256WITHRSA", TeleTrusTObjectIdentifiers.rsaSignatureWithripemd256); algorithms.put("SHA1WITHDSA", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("DSAWITHSHA1", X9ObjectIdentifiers.id_dsa_with_sha1); algorithms.put("SHA224WITHDSA", NISTObjectIdentifiers.dsa_with_sha224); algorithms.put("SHA256WITHDSA", NISTObjectIdentifiers.dsa_with_sha256); algorithms.put("SHA384WITHDSA", NISTObjectIdentifiers.dsa_with_sha384); algorithms.put("SHA512WITHDSA", NISTObjectIdentifiers.dsa_with_sha512); algorithms.put("SHA1WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("ECDSAWITHSHA1", X9ObjectIdentifiers.ecdsa_with_SHA1); algorithms.put("SHA224WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA224); algorithms.put("SHA256WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA256); algorithms.put("SHA384WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA384); algorithms.put("SHA512WITHECDSA", X9ObjectIdentifiers.ecdsa_with_SHA512); algorithms.put("GOST3411WITHGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHGOST3410-94", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); algorithms.put("GOST3411WITHECGOST3410", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHECGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); algorithms.put("GOST3411WITHGOST3410-2001", CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // According to RFC 3279, the ASN.1 encoding SHALL (id-dsa-with-sha1) or MUST (ecdsa-with-SHA*) omit the parameters field. // The parameters field SHALL be NULL for RSA based signature algorithms. // noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA1); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA224); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA256); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA384); noParams.add(X9ObjectIdentifiers.ecdsa_with_SHA512); noParams.add(X9ObjectIdentifiers.id_dsa_with_sha1); noParams.add(NISTObjectIdentifiers.dsa_with_sha224); noParams.add(NISTObjectIdentifiers.dsa_with_sha256); noParams.add(NISTObjectIdentifiers.dsa_with_sha384); noParams.add(NISTObjectIdentifiers.dsa_with_sha512); // // RFC 4491 // noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_94); noParams.add(CryptoProObjectIdentifiers.gostR3411_94_with_gostR3410_2001); // // explicit params // AlgorithmIdentifier sha1AlgId = new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1, new DERNull()); params.put("SHA1WITHRSAANDMGF1", creatPSSParams(sha1AlgId, 20)); AlgorithmIdentifier sha224AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha224, new DERNull()); params.put("SHA224WITHRSAANDMGF1", creatPSSParams(sha224AlgId, 28)); AlgorithmIdentifier sha256AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, new DERNull()); params.put("SHA256WITHRSAANDMGF1", creatPSSParams(sha256AlgId, 32)); AlgorithmIdentifier sha384AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha384, new DERNull()); params.put("SHA384WITHRSAANDMGF1", creatPSSParams(sha384AlgId, 48)); AlgorithmIdentifier sha512AlgId = new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha512, new DERNull()); params.put("SHA512WITHRSAANDMGF1", creatPSSParams(sha512AlgId, 64)); } private static RSASSAPSSparams creatPSSParams(AlgorithmIdentifier hashAlgId, int saltSize) { return new RSASSAPSSparams( hashAlgId, new AlgorithmIdentifier(PKCSObjectIdentifiers.id_mgf1, hashAlgId), new DERInteger(saltSize), new DERInteger(1)); } static DERObjectIdentifier getAlgorithmOID( String algorithmName) { algorithmName = Strings.toUpperCase(algorithmName); if (algorithms.containsKey(algorithmName)) { return (DERObjectIdentifier)algorithms.get(algorithmName); } return new DERObjectIdentifier(algorithmName); } static AlgorithmIdentifier getSigAlgID( DERObjectIdentifier sigOid, String algorithmName) { if (noParams.contains(sigOid)) { return new AlgorithmIdentifier(sigOid); } algorithmName = Strings.toUpperCase(algorithmName); if (params.containsKey(algorithmName)) { return new AlgorithmIdentifier(sigOid, (DEREncodable)params.get(algorithmName)); } else { return new AlgorithmIdentifier(sigOid, new DERNull()); } } @SuppressWarnings("rawtypes") static Iterator getAlgNames() { Enumeration e = algorithms.keys(); List l = new ArrayList(); while (e.hasMoreElements()) { l.add(e.nextElement()); } return l.iterator(); } static Signature getSignatureInstance( String algorithm) throws NoSuchAlgorithmException { return Signature.getInstance(algorithm); } static Signature getSignatureInstance( String algorithm, String provider) throws NoSuchProviderException, NoSuchAlgorithmException { if (provider != null) { return Signature.getInstance(algorithm, provider); } else { return Signature.getInstance(algorithm); } } static byte[] calculateSignature( DERObjectIdentifier sigOid, String sigName, PrivateKey key, SecureRandom random, ASN1Encodable object) throws IOException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature sig; if (sigOid == null) { throw new IllegalStateException("no signature algorithm specified"); } sig = X509Util.getSignatureInstance(sigName); if (random != null) { sig.initSign(key, random); } else { sig.initSign(key); } sig.update(object.getEncoded(ASN1Encodable.DER)); return sig.sign(); } static byte[] calculateSignature( DERObjectIdentifier sigOid, String sigName, String provider, PrivateKey key, SecureRandom random, ASN1Encodable object) throws IOException, NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException, SignatureException { Signature sig; if (sigOid == null) { throw new IllegalStateException("no signature algorithm specified"); } sig = X509Util.getSignatureInstance(sigName, provider); if (random != null) { sig.initSign(key, random); } else { sig.initSign(key); } sig.update(object.getEncoded(ASN1Encodable.DER)); return sig.sign(); } static X509Principal convertPrincipal( X500Principal principal) { try { return new X509Principal(principal.getEncoded()); } catch (IOException e) { throw new IllegalArgumentException("cannot convert principal"); } } static class Implementation { Object engine; Provider provider; Implementation( Object engine, Provider provider) { this.engine = engine; this.provider = provider; } Object getEngine() { return engine; } Provider getProvider() { return provider; } } /** * see if we can find an algorithm (or its alias and what it represents) in * the property table for the given provider. */ static Implementation getImplementation( String baseName, String algorithm, Provider prov) throws NoSuchAlgorithmException { algorithm = Strings.toUpperCase(algorithm); String alias; while ((alias = prov.getProperty("Alg.Alias." + baseName + "." + algorithm)) != null) { algorithm = alias; } String className = prov.getProperty(baseName + "." + algorithm); if (className != null) { try { @SuppressWarnings("rawtypes") Class cls; ClassLoader clsLoader = prov.getClass().getClassLoader(); if (clsLoader != null) { cls = clsLoader.loadClass(className); } else { cls = Class.forName(className); } return new Implementation(cls.newInstance(), prov); } catch (ClassNotFoundException e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but no class \"" + className + "\" found!"); } catch (Exception e) { throw new IllegalStateException( "algorithm " + algorithm + " in provider " + prov.getName() + " but class \"" + className + "\" inaccessible!"); } } throw new NoSuchAlgorithmException("cannot find implementation " + algorithm + " for provider " + prov.getName()); } /** * return an implementation for a given algorithm/provider. * If the provider is null, we grab the first avalaible who has the required algorithm. */ static Implementation getImplementation( String baseName, String algorithm) throws NoSuchAlgorithmException { Provider[] prov = Security.getProviders(); // // search every provider looking for the algorithm we want. // for (int i = 0; i != prov.length; i++) { // // try case insensitive // Implementation imp = getImplementation(baseName, Strings.toUpperCase(algorithm), prov[i]); if (imp != null) { return imp; } try { imp = getImplementation(baseName, algorithm, prov[i]); } catch (NoSuchAlgorithmException e) { // continue } } throw new NoSuchAlgorithmException("cannot find implementation " + algorithm); } static Provider getProvider(String provider) throws NoSuchProviderException { Provider prov = Security.getProvider(provider); if (prov == null) { throw new NoSuchProviderException("Provider " + provider + " not found"); } return prov; } }
CertificatePoliciesInfo.java
package com.secpki.jce.demo; /** * */ import java.util.Enumeration; import java.util.Vector; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.DEREncodable; import org.bouncycastle.asn1.DERInteger; import org.bouncycastle.asn1.DERObject; import org.bouncycastle.asn1.DERObjectIdentifier; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.x509.DisplayText; import org.bouncycastle.asn1.x509.NoticeReference; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.PolicyQualifierId; import org.bouncycastle.asn1.x509.PolicyQualifierInfo; import org.bouncycastle.asn1.x509.UserNotice; /** * @author TBear * */ public class CertificatePoliciesInfo implements DEREncodable{ public CertificatePoliciesInfo(){ certPolicies = new ASN1EncodableVector(); } public void add(String policy) { certPolicies.add(new PolicyInformation(new DERObjectIdentifier(policy))); } public void add(String policy,String cps) { ASN1EncodableVector policyQualifiers = new ASN1EncodableVector(); PolicyQualifierInfo qualifierInfo = new PolicyQualifierInfo(cps); policyQualifiers.add(qualifierInfo.getDERObject()); certPolicies.add(new PolicyInformation(new DERObjectIdentifier(policy),new DERSequence(policyQualifiers))); } public void add(String policy,Vector<String> cpss,Vector<UserNotice> userNotices) { ASN1EncodableVector policyQualifiers = new ASN1EncodableVector(); for(int i=0;i<cpss.size();i++) { String cps = cpss.elementAt(i); PolicyQualifierInfo qualifierInfo = new PolicyQualifierInfo(cps); policyQualifiers.add(qualifierInfo.toASN1Object()); } for(int i=0;i<userNotices.size();i++) { UserNotice userNotice = userNotices.elementAt(i); PolicyQualifierInfo qualifierInfo = new PolicyQualifierInfo(PolicyQualifierId.id_qt_unotice,userNotice.toASN1Object()); policyQualifiers.add(qualifierInfo.toASN1Object()); } if(policyQualifiers.size()==0){ certPolicies.add(new PolicyInformation(new DERObjectIdentifier(policy))); } else{ certPolicies.add(new PolicyInformation(new DERObjectIdentifier(policy),new DERSequence(policyQualifiers))); } } public void add(String policy,ASN1Sequence qualifierInfo) { certPolicies.add(new PolicyInformation(new DERObjectIdentifier(policy),qualifierInfo)); } public DERObject getDERObject() { return new DERSequence(certPolicies); } public static UserNotice makeUserNotice(String orgType,String org,Vector<Integer> nums,String displayTextType,String displayText) { NoticeReference noticeReference = null; DisplayText text = null; int iType = 2; if((org!=null)&&(nums.size()>0)){ if(orgType!=null){ if(displayTextType.equalsIgnoreCase("IA5STRING")){ iType = 0; } else if(displayTextType.equalsIgnoreCase("BMPSTRING")){ iType = 1; } else if(displayTextType.equalsIgnoreCase("UTF8STRING")){ iType = 2; } else if(displayTextType.equalsIgnoreCase("VISIBLESTRING")){ iType = 3; } } ASN1EncodableVector asn1encodablevector = new ASN1EncodableVector(); DERInteger derinteger; for(Enumeration<Integer> enumeration = nums.elements(); enumeration.hasMoreElements(); asn1encodablevector.add(derinteger)) { Integer integer = enumeration.nextElement(); derinteger = new DERInteger(integer.intValue()); } noticeReference = new NoticeReference(iType,org, new DERSequence(asn1encodablevector)); } if(displayText!=null){ if(displayTextType==null){ text = new DisplayText(displayText); } else{ if(displayTextType.equalsIgnoreCase("IA5STRING")){ text = new DisplayText(DisplayText.CONTENT_TYPE_IA5STRING,displayText); } else if(displayTextType.equalsIgnoreCase("BMPSTRING")){ text = new DisplayText(DisplayText.CONTENT_TYPE_BMPSTRING,displayText); } else if(displayTextType.equalsIgnoreCase("UTF8STRING")){ text = new DisplayText(DisplayText.CONTENT_TYPE_UTF8STRING,displayText); } else if(displayTextType.equalsIgnoreCase("VISIBLESTRING")){ text = new DisplayText(DisplayText.CONTENT_TYPE_VISIBLESTRING,displayText); } else{ text = new DisplayText(displayText); } } } UserNotice un = new UserNotice(noticeReference,text); return un; } public static UserNotice makeUserNotice(String displayText) { UserNotice un = new UserNotice(null,displayText); return un; } private ASN1EncodableVector certPolicies; }