日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java keystore ca_PKCS12 Java Keystore from CA and User certificate in java

發(fā)布時間:2024/7/19 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java keystore ca_PKCS12 Java Keystore from CA and User certificate in java 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

問題

I've recently been put in charge of mocking up an Apple product (iPhone Configuration Utility) in Java. One of the sections I've been a bit stuck on is a part about Exchange ActiveSync. In there, it allows you to select a certificate from your Keychain to use as credentials for your EAS account. After some research, I found that it's actually creating a PKCS12 keystore, inserting the private key of the certificate I selected, and encoding that into XML. So far not a big deal. If I create a .p12 file with Keychain Access it uploads without a problem. But I run into a problem when I try to bring that over to Java.

Say I export one of those certs that I had used earlier with the .p12 file as a .cer file (this is what we are expecting to get in the environment). Now when I upload it into Java I get a Certificate object as follows...

KeyStore ks = java.security.KeyStore.getInstance("PKCS12");

ks.load(null, "somePassword".toCharArray());

CertificateFactory cf = CertificateFactory.getInstance("X.509", new BouncyCastleProvider());

java.security.cert.Certificate userCert = cf.generateCertificate(new FileInputStream("/Users/me/Desktop/RecentlyExportedCert.cer"));

But when I try...

ks.setCertificateEntry("SomeAlias", userCert);

I get the exception...

java.security.KeyStoreException: TrustedCertEntry not supported

So from certs I move onto keys. But with those Certificates (I got the CA Cert as well), I'm only able to access the public key, not the private. And if I attempt to add the public key like so...

java.security.cert.Certificate[] chain = {CACert};

ks.setKeyEntry("SomeAlias", userCert.getPublicKey().getEncoded(), chain);

I get...

java.security.KeyStoreException: Private key is not stored as PKCS#8 EncryptedPrivateKeyInfo: java.io.IOException: DerValue.getOctetString, not an Octet String: 3

So now I'm here. Does anyone have any idea how to get a private key from a .cer file into a PKCS12 keystore in Java? Am I even on the right track?

Thanks in advance!

回答1:

The PKCS#12 format is intended for storing a private key associated with a certificate chain, and both are required (although you might not need the whole chain).

Although the PKCS12 keystore type does a good job for mapping this format to a Java KeyStore, not everything is supported for this reason.

What you're trying to do in your first attempt is storing a certificate on its own, which won't work.

What you're trying to do in your second attempt (ks.setKeyEntry("SomeAlias", userCert.getPublicKey().getEncoded(), chain)) is to for a public key in place of what should be a private key (see KeyStore#setKeyEntry).

.cer file tend to be just for certificates not private keys (although of course, the extension is ultimately just an indication). If you export your .cer file from Keychain Access.app, you won't get the private key with it (that's what the .p12 export format is for).

EDIT about KeychainStore:

If the reason you're trying to do this conversion is ultimately to access private keys and certificates that are already in the keychain you could load them from the KeychainStore directly:

KeyStore ks = KeyStore.getInstance("KeychainStore", "Apple");

ks.load(null, "-".toCharArray());

A couple of notes for this:

Any non-null, non-empty password will do to use the private key (e.g. "-".toCharArray()), as access will be prompted by the OS's security service (like it would in other applications).

As far as I'm aware, there is still a bug and it only allows access to one private key/certificate pair (even if a number of pairs of private key/certificate pairs are present in the keychain)

回答2:

http://www.docjar.com/html/api/org/bouncycastle/jce/examples/PKCS12Example.java.html

This is how to add a certificate with a associating private key to a PKCS12 keystore.

When you are using client authentication, the keystore needs to contain also the private key, in that case you use KeyStore.getInstance("PKCS12").

When youre not using client authentication but only server authentication(and private key will not be added to keystore, since it belongs to the server), its better to use

KeyStore.getInstance("JKS"), than you can add multiple certificates with an alias to that one keystore.

When you are using PKCS12, as far as I know, you can only add 1 certificate(you have to add the whole certificate chain) associated with the private key, you want to use for that certificate.

回答3:

I'm a couple years late to the party but this took me a few hours to get working correctly,

so I thought it was worth posting a working solution.

This solution uses 1) A .p12 / PKCS12 certificate

and 2) a CA not in the default TrustManager (and you want to add it programatically rather than adding to the default TrustManager). 3) No third party cryptography libraries, just HttpClient to bring it all together.

I've also added a few helpful keytool and openssl commands in the JavaDoc for working with certificates, as that is an art in itself.

// Stitch it all together with HttpClient

CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(getSSLSocketFactory()).build();

private SSLConnectionSocketFactory getSSLSocketFactory() {

try {

SSLContext sslContext = SSLContext.getInstance("TLS");

KeyManager[] keyManager = getKeyManager("pkcs12", "path/to/cert.p12"), "p12_password"));

TrustManager[] trustManager = getTrustManager("jks", "path/to/CA.truststore", "trust_store_password"));

sslContext.init(keyManager, trustManager, new SecureRandom());

return new SSLConnectionSocketFactory(sslContext);

} catch (Exception e) {

throw new RuntimeException("Unable to setup keystore and truststore", e);

}

}

/**

* Some useful commands for looking at the client certificate and private key:

* keytool -keystore certificate.p12 -list -storetype pkcs12 -v

* openssl pkcs12 -info -in certificate.p12

*/

private KeyManager[] getKeyManager(String keyStoreType, String keyStoreFile, String keyStorePassword) throws Exception {

KeyStore keyStore = KeyStore.getInstance(keyStoreType);

KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());

keyStore.load(this.getClass().getClassLoader().getResourceAsStream(keyStoreFile), keyStorePassword.toCharArray());

kmf.init(keyStore, keyStorePassword.toCharArray());

return kmf.getKeyManagers();

}

/**

* Depending on what format (pem / cer / p12) you have received the CA in, you will need to use a combination of openssl and keytool

* to convert it to JKS format in order to be loaded into the truststore using the method below.

*

* You could of course use keytool to import this into the JREs TrustStore - my situation mandated I create it on the fly.

*

* Useful command to look at the CA certificate:

* keytool -keystore root_ca.truststore -list -storetype jks -v

*

*/

private TrustManager[] getTrustManager(String trustStoreType, String trustStoreFile, String trustStorePassword) throws Exception {

KeyStore trustStore = KeyStore.getInstance(trustStoreType);

TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());

trustStore.load(this.getClass().getClassLoader().getResourceAsStream(trustStoreFile), trustStorePassword.toCharArray());

tmf.init(trustStore);

return tmf.getTrustManagers();

}

來源:https://stackoverflow.com/questions/3614239/pkcs12-java-keystore-from-ca-and-user-certificate-in-java

總結(jié)

以上是生活随笔為你收集整理的java keystore ca_PKCS12 Java Keystore from CA and User certificate in java的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。