在充气城堡的示例中,我找到了以下代码:
package crypto; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.KeyFactory; import java.security.KeyStore; import java.security.PrivateKey; import java.security.Security; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.security.spec.PKCS8EncodedKeySpec; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.bouncycastle.asn1.ASN1Encoding; import org.bouncycastle.asn1.DERBMPString; import org.bouncycastle.asn1.nist.NISTObjectIdentifiers; import org.bouncycastle.asn1.pkcs.Attribute; import org.bouncycastle.asn1.pkcs.ContentInfo; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.asn1.x509.SubjectKeyIdentifier; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.operator.InputDecryptorProvider; import org.bouncycastle.operator.OutputEncryptor; import org.bouncycastle.operator.bc.BcDefaultDigestProvider; import org.bouncycastle.pkcs.PKCS12PfxPdu; import org.bouncycastle.pkcs.PKCS12PfxPduBuilder; import org.bouncycastle.pkcs.PKCS12SafeBag; import org.bouncycastle.pkcs.PKCS12SafeBagBuilder; import org.bouncycastle.pkcs.PKCS12SafeBagFactory; import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; import org.bouncycastle.pkcs.bc.BcPKCS12MacCalculatorBuilderProvider; import org.bouncycastle.pkcs.jcajce.JcaPKCS12SafeBagBuilder; import org.bouncycastle.pkcs.jcajce.JcePKCS12MacCalculatorBuilder; import org.bouncycastle.pkcs.jcajce.JcePKCSPBEInputDecryptorProviderBuilder; import org.bouncycastle.pkcs.jcajce.JcePKCSPBEOutputEncryptorBuilder; import org.bouncycastle.util.io.Streams; public class PKCS12 { public static void main(String[] args) throws Exception { Security.addProvider(new BouncyCastleProvider()); KeyStore credentials = JcaUtils.createCredentials(); PrivateKey key = (PrivateKey)credentials.getKey(JcaUtils.END_ENTITY_ALIAS, JcaUtils.KEY_PASSWD); Certificate[] chain = credentials.getCertificateChain(JcaUtils.END_ENTITY_ALIAS); createPKCS12File(new FileOutputStream("id.p12"), key, chain); // // first do a "blow by blow" read of the PKCS#12 file. // PKCS12PfxPdu pfx = readPKCS12File(new FileInputStream("id.p12")); // // or alternately just load it up using a KeyStore // KeyStore pkcs12Store = KeyStore.getInstance("PKCS12", "BC"); pkcs12Store.load(new FileInputStream("id.p12"), JcaUtils.KEY_PASSWD); System.out.println("########## KeyStore Dump"); for (Enumeration en = pkcs12Store.aliases(); en.hasMoreElements();) { String alias = (String)en.nextElement(); if (pkcs12Store.isCertificateEntry(alias)) { System.out.println("Certificate Entry: " + alias + ", Subject: " + (((X509Certificate)pkcs12Store.getCertificate(alias)).getSubjectDN())); } else if (pkcs12Store.isKeyEntry(alias)) { System.out.println("Key Entry: " + alias + ", Subject: " + (((X509Certificate)pkcs12Store.getCertificate(alias)).getSubjectDN())); } } System.out.println(); } private static void createPKCS12File(OutputStream pfxOut, PrivateKey key, Certificate[] chain) throws Exception { OutputEncryptor encOut = new JcePKCSPBEOutputEncryptorBuilder(NISTObjectIdentifiers.id_aes256_CBC).setProvider("BC").build(JcaUtils.KEY_PASSWD); PKCS12SafeBagBuilder taCertBagBuilder = new JcaPKCS12SafeBagBuilder((X509Certificate)chain[2]); taCertBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString("Bouncy Primary Certificate")); PKCS12SafeBagBuilder caCertBagBuilder = new JcaPKCS12SafeBagBuilder((X509Certificate)chain[1]); caCertBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString("Bouncy Intermediate Certificate")); JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder((X509Certificate)chain[0]); eeCertBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString("Eric's Key")); SubjectKeyIdentifier pubKeyId = extUtils.createSubjectKeyIdentifier(chain[0].getPublicKey()); eeCertBagBuilder.addBagAttribute(PKCS12SafeBag.localKeyIdAttribute, pubKeyId); PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(key, encOut); keyBagBuilder.addBagAttribute(PKCS12SafeBag.friendlyNameAttribute, new DERBMPString("Eric's Key")); keyBagBuilder.addBagAttribute(PKCS12SafeBag.localKeyIdAttribute, pubKeyId); PKCS12PfxPduBuilder builder = new PKCS12PfxPduBuilder(); builder.addData(keyBagBuilder.build()); builder.addEncryptedData(new JcePKCSPBEOutputEncryptorBuilder(PKCSObjectIdentifiers.pbeWithSHAAnd128BitRC2_CBC).setProvider("BC").build(JcaUtils.KEY_PASSWD), new PKCS12SafeBag[]{eeCertBagBuilder.build(), caCertBagBuilder.build(), taCertBagBuilder.build()}); PKCS12PfxPdu pfx = builder.build(new JcePKCS12MacCalculatorBuilder(NISTObjectIdentifiers.id_sha256), JcaUtils.KEY_PASSWD); // make sure we don't include indefinite length encoding pfxOut.write(pfx.getEncoded(ASN1Encoding.DL)); pfxOut.close(); } private static PKCS12PfxPdu readPKCS12File(InputStream pfxIn) throws Exception { PKCS12PfxPdu pfx = new PKCS12PfxPdu(Streams.readAll(pfxIn)); if (!pfx.isMacValid(new BcPKCS12MacCalculatorBuilderProvider(BcDefaultDigestProvider.INSTANCE), JcaUtils.KEY_PASSWD)) { System.err.println("PKCS#12 MAC test failed!"); } ContentInfo[] infos = pfx.getContentInfos(); Map certMap = new HashMap(); Map certKeyIds = new HashMap(); Map privKeyMap = new HashMap(); Map privKeyIds = new HashMap(); InputDecryptorProvider inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder() .setProvider("BC").build(JcaUtils.KEY_PASSWD); JcaX509CertificateConverter jcaConverter = new JcaX509CertificateConverter().setProvider("BC"); for (int i = 0; i != infos.length; i++) { if (infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i], inputDecryptorProvider); PKCS12SafeBag[] bags = dataFact.getSafeBags(); for (int b = 0; b != bags.length; b++) { PKCS12SafeBag bag = bags[b]; X509CertificateHolder certHldr = (X509CertificateHolder)bag.getBagValue(); X509Certificate cert = jcaConverter.getCertificate(certHldr); Attribute[] attributes = bag.getAttributes(); for (int a = 0; a != attributes.length; a++) { Attribute attr = attributes[a]; if (attr.getAttrType().equals(PKCS12SafeBag.friendlyNameAttribute)) { certMap.put(((DERBMPString)attr.getAttributeValues()[0]).getString(), cert); } else if (attr.getAttrType().equals(PKCS12SafeBag.localKeyIdAttribute)) { certKeyIds.put(attr.getAttributeValues()[0], cert); } } } } else { PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i]); PKCS12SafeBag[] bags = dataFact.getSafeBags(); PKCS8EncryptedPrivateKeyInfo encInfo = (PKCS8EncryptedPrivateKeyInfo)bags[0].getBagValue(); PrivateKeyInfo info = encInfo.decryptPrivateKeyInfo(inputDecryptorProvider); KeyFactory keyFact = KeyFactory .getInstance(info.getPrivateKeyAlgorithm().getAlgorithm().getId(), "BC"); PrivateKey privKey = keyFact.generatePrivate(new PKCS8EncodedKeySpec(info.getEncoded())); Attribute[] attributes = bags[0].getAttributes(); for (int a = 0; a != attributes.length; a++) { Attribute attr = attributes[a]; if (attr.getAttrType().equals(PKCS12SafeBag.friendlyNameAttribute)) { privKeyMap.put(((DERBMPString)attr.getAttributeValues()[0]).getString(), privKey); } else if (attr.getAttrType().equals(PKCS12SafeBag.localKeyIdAttribute)) { privKeyIds.put(privKey, attr.getAttributeValues()[0]); } } } } System.out.println("########## PFX Dump"); for (Iterator it = privKeyMap.keySet().iterator(); it.hasNext();) { String alias = (String)it.next(); System.out.println("Key Entry: " + alias + ", Subject: " + (((X509Certificate)certKeyIds.get(privKeyIds.get(privKeyMap.get(alias)))).getSubjectDN())); } for (Iterator it = certMap.keySet().iterator(); it.hasNext();) { String alias = (String)it.next(); System.out.println("Certificate Entry: " + alias + ", Subject: " + (((X509Certificate)certMap.get(alias)).getSubjectDN())); } System.out.println(); return pfx; } }
当我使用此代码编写p12时,我尝试使用openssl或钥匙串将其打开,并提示我输入密码。我用他们的密码
public static char[] KEY_PASSWD = "keyPassword".toCharArray();
尝试打开P12,但是它不起作用。此外,当我按原样运行此主要功能时,将执行此行
System.err.println("PKCS#12 MAC test failed!");
为了正确地在p12上输入密码,他们的示例有问题吗?我基本上是想做相当于
openssl pkcs12 -export -des3
如果有其他想法,也可以使用Bouncy Castle在Java中使用。
看NISTObjectIdentifiers可供选择,我看不到p12pbmac / sha1。这是我看到的:
public interface NISTObjectIdentifiers { ASN1ObjectIdentifier nistAlgorithm = new ASN1ObjectIdentifier("2.16.840.1.101.3.4"); ASN1ObjectIdentifier hashAlgs = nistAlgorithm.branch("2"); ASN1ObjectIdentifier id_sha256 = hashAlgs.branch("1"); ASN1ObjectIdentifier id_sha384 = hashAlgs.branch("2"); ASN1ObjectIdentifier id_sha512 = hashAlgs.branch("3"); ASN1ObjectIdentifier id_sha224 = hashAlgs.branch("4"); ASN1ObjectIdentifier id_sha512_224 = hashAlgs.branch("5"); ASN1ObjectIdentifier id_sha512_256 = hashAlgs.branch("6"); ASN1ObjectIdentifier id_sha3_224 = hashAlgs.branch("7"); ASN1ObjectIdentifier id_sha3_256 = hashAlgs.branch("8"); ASN1ObjectIdentifier id_sha3_384 = hashAlgs.branch("9"); ASN1ObjectIdentifier id_sha3_512 = hashAlgs.branch("10"); ASN1ObjectIdentifier id_shake128 = hashAlgs.branch("11"); ASN1ObjectIdentifier id_shake256 = hashAlgs.branch("12"); ASN1ObjectIdentifier id_hmacWithSHA3_224 = hashAlgs.branch("13"); ASN1ObjectIdentifier id_hmacWithSHA3_256 = hashAlgs.branch("14"); ASN1ObjectIdentifier id_hmacWithSHA3_384 = hashAlgs.branch("15"); ASN1ObjectIdentifier id_hmacWithSHA3_512 = hashAlgs.branch("16"); ASN1ObjectIdentifier aes = nistAlgorithm.branch("1"); ASN1ObjectIdentifier id_aes128_ECB = aes.branch("1"); ASN1ObjectIdentifier id_aes128_CBC = aes.branch("2"); ASN1ObjectIdentifier id_aes128_OFB = aes.branch("3"); ASN1ObjectIdentifier id_aes128_CFB = aes.branch("4"); ASN1ObjectIdentifier id_aes128_wrap = aes.branch("5"); ASN1ObjectIdentifier id_aes128_GCM = aes.branch("6"); ASN1ObjectIdentifier id_aes128_CCM = aes.branch("7"); ASN1ObjectIdentifier id_aes128_wrap_pad = aes.branch("8"); ASN1ObjectIdentifier id_aes192_ECB = aes.branch("21"); ASN1ObjectIdentifier id_aes192_CBC = aes.branch("22"); ASN1ObjectIdentifier id_aes192_OFB = aes.branch("23"); ASN1ObjectIdentifier id_aes192_CFB = aes.branch("24"); ASN1ObjectIdentifier id_aes192_wrap = aes.branch("25"); ASN1ObjectIdentifier id_aes192_GCM = aes.branch("26"); ASN1ObjectIdentifier id_aes192_CCM = aes.branch("27"); ASN1ObjectIdentifier id_aes192_wrap_pad = aes.branch("28"); ASN1ObjectIdentifier id_aes256_ECB = aes.branch("41"); ASN1ObjectIdentifier id_aes256_CBC = aes.branch("42"); ASN1ObjectIdentifier id_aes256_OFB = aes.branch("43"); ASN1ObjectIdentifier id_aes256_CFB = aes.branch("44"); ASN1ObjectIdentifier id_aes256_wrap = aes.branch("45"); ASN1ObjectIdentifier id_aes256_GCM = aes.branch("46"); ASN1ObjectIdentifier id_aes256_CCM = aes.branch("47"); ASN1ObjectIdentifier id_aes256_wrap_pad = aes.branch("48"); ASN1ObjectIdentifier sigAlgs = nistAlgorithm.branch("3"); ASN1ObjectIdentifier id_dsa_with_sha2 = sigAlgs; ASN1ObjectIdentifier dsa_with_sha224 = sigAlgs.branch("1"); ASN1ObjectIdentifier dsa_with_sha256 = sigAlgs.branch("2"); ASN1ObjectIdentifier dsa_with_sha384 = sigAlgs.branch("3"); ASN1ObjectIdentifier dsa_with_sha512 = sigAlgs.branch("4"); ASN1ObjectIdentifier id_dsa_with_sha3_224 = sigAlgs.branch("5"); ASN1ObjectIdentifier id_dsa_with_sha3_256 = sigAlgs.branch("6"); ASN1ObjectIdentifier id_dsa_with_sha3_384 = sigAlgs.branch("7"); ASN1ObjectIdentifier id_dsa_with_sha3_512 = sigAlgs.branch("8"); ASN1ObjectIdentifier id_ecdsa_with_sha3_224 = sigAlgs.branch("9"); ASN1ObjectIdentifier id_ecdsa_with_sha3_256 = sigAlgs.branch("10"); ASN1ObjectIdentifier id_ecdsa_with_sha3_384 = sigAlgs.branch("11"); ASN1ObjectIdentifier id_ecdsa_with_sha3_512 = sigAlgs.branch("12"); ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_224 = sigAlgs.branch("13"); ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_256 = sigAlgs.branch("14"); ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_384 = sigAlgs.branch("15"); ASN1ObjectIdentifier id_rsassa_pkcs1_v1_5_with_sha3_512 = sigAlgs.branch("16"); }
元:这是一种解决方法,不能解决所提出的Q问题,但需要格式化。
要创建PKCS12的简单方法, 只需KeyStore按照其javadoc中的说明 使用即可 ,它应该在您的IDE 或Oracle网站上提供。这是一个最小的示例,结合了javadoc中的代码。由于您的Q不会显示您 从 何处获取createCredentials数据,对于本示例,我只是从现有的JKS中读取;根据需要更改此设置。并使用更好的密码! __
KeyStore
createCredentials
我将使用默认提供程序(SunJSSE)和BC提供程序进行演示。我在最终测试中发现了一个警告:BC需要在Oracle Java上安装“无限强度策略”-至少到j8。据说这个“功能”终于在j9中被删除了,但是我还没有测试。即使TDES 强度 只有112,应该允许,它也可能将168的TDES密钥大小视为超过128 。
char[] pw = "password".toCharArray(); // dummy for test boolean useBC = System.getProperty("useBC")!=null; KeyStore jks = KeyStore.getInstance("JKS"); InputStream f1 = new FileInputStream ("old.jks"); jks.load(f1, pw); f1.close(); PrivateKey pkey = (PrivateKey)jks.getKey("mykey", pw); Certificate[] chain = jks.getCertificateChain("mykey"); // only needed once, and not at all if pre-configured in java.security if(useBC) Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // then do something like this KeyStore p12 = useBC? KeyStore.getInstance("PKCS12","BC"): KeyStore.getInstance("PKCS12"); p12.load(null); p12.setKeyEntry("mykey", pkey, pw, chain); OutputStream f2 = new FileOutputStream ("new.p12"); p12.store(f2,pw); f2.close();