从密钥库获取私钥

时间:2015-02-11 06:26:27

标签: java keystore jks

我有.cer由其他人签名。从那里我使用下面的工具创建私钥文件.jks

keytool -importcert -file aaa.cer -keystore aaa.jks -alias abcd

输出:

Owner: CN=Sample, EMAILADDRESS=hello@gmail.com, C=IN, OU=Director, O=ABCDEF
Issuer: C=IN, O=ABCDEF, CN=Owner
Serial number: 1
Valid from: Fri Feb 20 17:11:48 IST 2015 until: Mon Feb 19 17:11:48 IST 2018
Certificate fingerprints:
         MD5:  59:9A:1C:FA:F7:F3:45:CA:06:1D:FA:AA:13:B7:68:1C
         SHA1: 3B:4E:4B:5A:57:9E:DC:D6:3E:3C:EB:18:91:60:B6:EA:9D:FB:6E:DA
         SHA256: 37:04:49:08:0A:2E:1D:5D:58:51:0E:69:C3:85:5C:45:55:F0:D9:6B:27:EE:99:6B:E7:08:B7:4A:EA:E0:83:EC
         Signature algorithm name: SHA1withRSA
         Version: 3
Trust this certificate? [no]:  yes
Certificate was added to keystore

相同的证书我需要在XML上签名,因为我写了下面的代码,

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document inputDocument = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(xmlDoc)));
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("../cer/aaa.jks"), "xxxxxxx".toCharArray());
KeyStore.PrivateKeyEntry keyEntry =(KeyStore.PrivateKeyEntry) ks.getEntry("abcd", new KeyStore.PasswordProtection("xxxxxxx".toCharArray()));
X509Certificate x509Cert = (X509Certificate) keyEntry.getCertificate();
X509Certificate x509Cert = (X509Certificate) keyEntry.getCertificate();
XMLSignatureFactory fac = XMLSignatureFactory.getInstance(MEC_TYPE);
Reference ref = fac.newReference(WHOLE_DOC_URI, fac.newDigestMethod(DigestMethod.SHA1, null), Collections.singletonList(fac.newTransform(Transform.ENVELOPED,(TransformParameterSpec) null)), null, null);
SignedInfo sInfo = fac.newSignedInfo(fac.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,(C14NMethodParameterSpec) null), fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),Collections.singletonList(ref));
KeyInfo kInfo = getKeyInfo(x509Cert, fac);
DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(),inputDocument.getDocumentElement());
XMLSignature signature = fac.newXMLSignature(sInfo,kInfo);
signature.sign(dsc);
Node node = dsc.getParent();
Document signedDocument = node.getOwnerDocument();  
StringWriter stringWriter = new StringWriter();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(signedDocument), new StreamResult(stringWriter));
return stringWriter.getBuffer().toString();

但是我在第6行得到了例外。

堆栈跟踪:

java.lang.UnsupportedOperationException: trusted certificate entries are not password-protected
    at java.security.KeyStoreSpi.engineGetEntry(Unknown Source)
    at java.security.KeyStore.getEntry(Unknown Source)

请帮助解决此问题。

1 个答案:

答案 0 :(得分:1)

.cer文件仅包含公钥以及来自CA的一些签名信息,因此您的密钥库中没有要检索的私钥。您导入.cer文件所做的是将其添加到您的JVM将信任的证书集中。

您需要做的工作是用于为此证书生成证书签名请求的私钥文件。如果它不是使用keytool在java-keystore中创建的,则可能需要执行一些额外的步骤,因为您可以直接将私钥和证书导入.jks - 文件,但是必须创建一个中间PKCS12-keystore。使用openssl可能会这样:

# Create PKCS12 keystore from private key and public certificate.
openssl pkcs12 -export -name myservercert -in certificate.cer -inkey server.key -out keystore.p12
# Convert PKCS12 keystore into a JKS keystore
keytool -importkeystore -destkeystore mykeystore.jks -srckeystore keystore.p12 -srcstoretype pkcs12 -alias abcd