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;
}