我正在尝试使用bouncycastle库为S / MIME创建自签名证书。我在互联网上使用了一些例子和一些帖子。代码如下。
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA", "BC");
kpGen.initialize(1024, random);
KeyPair keyPair = kpGen.generateKeyPair();
PublicKey RSAPubKey = keyPair.getPublic();
PrivateKey RSAPrivateKey = keyPair.getPrivate();
X500Name subjectDN = new X500Name("CN =" + domain);
SubjectPublicKeyInfo pubKeyInfo = SubjectPublicKeyInfo.getInstance(ASN1Sequence.getInstance(RSAPubKey.getEncoded()));
X509v3CertificateBuilder v3CertBuild;
v3CertBuild = new X509v3CertificateBuilder(subjectDN,
BigInteger.valueOf(new SecureRandom().nextInt()),
new Date(System.currentTimeMillis()),
new Date(System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 365 * 10)),
subjectDN,
pubKeyInfo);
DigestCalculator digCalc = new BcDigestCalculatorProvider().get(new AlgorithmIdentifier(OIWObjectIdentifiers.idSHA1));
X509ExtensionUtils x509ExtensionUtils = new X509ExtensionUtils(digCalc);
v3CertBuild.addExtension(Extension.authorityKeyIdentifier, false, x509ExtensionUtils.createAuthorityKeyIdentifier(pubKeyInfo).getKeyIdentifier());
v3CertBuild.addExtension(Extension.subjectKeyIdentifier, false, x509ExtensionUtils.createSubjectKeyIdentifier(pubKeyInfo).getKeyIdentifier());
v3CertBuild.addExtension(Extension.keyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment));
ASN1EncodableVector purposes = new ASN1EncodableVector();
purposes.add(KeyPurposeId.id_kp_emailProtection);
v3CertBuild.addExtension(Extension.extendedKeyUsage, false, purposes.get(0));
v3CertBuild.addExtension(Extension.basicConstraints, true, new BasicConstraints(0));
GeneralName[] genNames = new GeneralName[1];
genNames[0] = new GeneralName(GeneralName.rfc822Name, new DERIA5String(domain));
v3CertBuild.addExtension(Extension.subjectAlternativeName, false, new GeneralNames(genNames));
ContentSigner sigGen = new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").build(RSAPrivateKey);
X509Certificate certificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate(v3CertBuild.build(sigGen));
PKCS12BagAttributeCarrier bagAttr = (PKCS12BagAttributeCarrier) certificate;
bagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
new DERBMPString(domain));
KeyStore kstore = KeyStore.getInstance("PKCS12", "BC");
X509Certificate[] chain = new X509Certificate[1];
chain[0] = certificate;
kstore.load(null, null);
FileOutputStream fOut = new FileOutputStream(domain+".p12");
PKCS12BagAttributeCarrier bagAttr1 = (PKCS12BagAttributeCarrier) keyPair.getPrivate();
bagAttr1.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_friendlyName,
new DERBMPString(domain));
bagAttr.setBagAttribute(
PKCSObjectIdentifiers.pkcs_9_at_localKeyId,
new SubjectKeyIdentifier(RSAPubKey.getEncoded()));
kstore.setKeyEntry(domain, RSAPrivateKey, null, chain);
kstore.store(fOut, password.toCharArray());
我有这个例外:
java.lang.RuntimeException: java.io.IOException: DER length more than 4 bytes: 39
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineGetCertificateChain(Unknown Source)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.getUsedCertificateSet(Unknown Source)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.doStore(Unknown Source)
at org.bouncycastle.jcajce.provider.keystore.pkcs12.PKCS12KeyStoreSpi.engineStore(Unknown Source)
at java.security.KeyStore.store(KeyStore.java:1377)
at javaapplication1.Certificate.createCert(Certificate.java:91)
at javaapplication1.JavaApplication1.main(JavaApplication1.java:38)
或者有时候:
java.lang.RuntimeException: java.io.IOException: unknown tag 29 encountered
java.lang.RuntimeException: java.io.EOFException: DEF length 64 object truncated by 46
它停在最后一行。搜索了很多关于这个例外,但仍然无法理解我的代码有什么问题。请帮我找一个解决方案...
答案 0 :(得分:1)
错误在于:
v3CertBuild.addExtension(Extension.authorityKeyIdentifier, false, x509ExtensionUtils.createAuthorityKeyIdentifier(pubKeyInfo).getKeyIdentifier());
v3CertBuild.addExtension(Extension.subjectKeyIdentifier, false, x509ExtensionUtils.createSubjectKeyIdentifier(pubKeyInfo).getKeyIdentifier());
getKeyIndentifier()是不必要的......