1

Current situation:

We do a POST to a certain url using HTTPS/SSL. For this to work my (former) colleague posted this question: Java HTTPS client certificate authentication

So basicly we have a keystore in .p12 format and the truststore is a .jks file.

We have no control over the server that receives our POST request.

Issue:

The server admins have provided us with some new .der files because their old certificate was about to expire.

As I'm fairly new to SSL certificates and keytool- and openssl-commands I have no idea how to proceed from here.

1) Is it necessary to generate new .p12 and .jks files? Or do I only need to generate a new .jks file?

2) How do I generate these files from a .der certificate? I have found some websites with the most keytool/openssl commands but I haven't been able to successfully generate what I need.

The last command I tried (to no avail) was:

keytool -storepass dsmserver -keystore c:\temp\newkeystore.jks -importcert -alias "c:\temp\newcert.der" -trustcacerts
Community
  • 1
  • 1
B.T.
  • 132
  • 2
  • 15

2 Answers2

3

Wait, which certificate expired? If it was theirs, there shouldn't have been any need to send you a new file (after all, you don't have to update your browser when, say, stackoverflow.com's SSL certificate expires and they install a new one). If you're doing mutual authentication (client certificate authentication), then there are four certificates involved: your certificate, their certificate, the certificate of the authority that signed your certificate, and the certificate of the authority that signed their certificate. They send you their certificate and you check to see that it was properly signed by a certificate authority that you trust (that's what the truststore is for - it's a list of the certificate authorities that you trust to sign certificates from their side). Subsequently, you send your certificate and they check to see that it was properly signed by a certificate authority that they trust. (Of course, all of this is automatically done for you behind the scenes in JSSE by the SSL handshake procedure)

Remember, a certificate is a (signed) assertion that such-and-such name is identified by a particular public key. So if their certificate expired, they'll generate a new one, get it signed by a CA that you already trust, and replace the old one with this one. When your software (automatically, as part of the behind-the-scenes SSL handshake) gets the new one, it will check to see who the signer ("issuer") was and if it's in your list of trusted authorities (and properly signed). If this checks out, you'll accept it automatically. They don't need to send you anything out-of-band to make this happen, unless they're changing certificate authorities and you don't already trust the new one. If so, you can use

keytool -import -keystore <truststore> -file <certificate file> -alias <someca>

If, on the other hand, your certificate is the one that expired, then they shouldn't be sending you anything unrequested. Instead, you should be generating a CSR via:

keytool -genkey -alias <myalias> -keystore <keystore>.p12 -storetype pkcs12
keytool -certreq -alias <myalias> -file request.csr -keystore <keystore>.p12 -storetype pkcs12

This will update the keystore with a new private key and create a file named "request.csr" which you should then send to them (or to a CA that's in their truststore) for a signature. They will respond with a signed certificate which you will then import back into your keystore using:

keytool -import -alias <myalias> -file <signed certificate>.cer

If I had to guess, it looks like they tried to perform these three steps for you, and tried to send you the certificate and the corresponding private key, which is invalid - Java will (rightly!) try its best to stop you from importing that because the private key itself was tainted when they sent it over an untrusted channel (e-mail, I presume?) This defeats the purpose of PKI - nobody should ever have access to your private key except for you.

Joshua Davies
  • 981
  • 9
  • 16
  • 2
    I see, that cleared some stuff up. What I understand so far: **Their** certificate expired and they sent all clients 3 things: a public key certificate, intermediate CA cert and root CA cert. I have no idea if they changed anything on CA-level. They also told me that my private key did not change... So to be safe, I add the new CA certs to my (pre-existing) jks file? – B.T. Apr 13 '12 at 12:34
  • Yes, all you should need to do is to add the intermediate cert to the truststore (which I believe you said was a JKS file). You can add the root cert, too, but you shouldn't need to, since their cert will have been signed with the intermediate (if the intermediate is trusted, the certificate is trusted). – Joshua Davies Apr 13 '12 at 13:54
  • 1
    So I added the intermed cert to my existing jks keystore (aka truststore) using: `keytool -trustcacerts -import -keystore existing.jks -file intemed_ca.der -alias servercert`. I'll test this today or tomorrow and post the followup info. – B.T. Apr 16 '12 at 12:36
  • 1
    It's been a while, but this solution works. All I needed to do was add the intermed cert to my existing keystore. Thanks! – B.T. May 03 '12 at 13:13
1

Download the file from the below link:ImportKey.Java

Run the following commands:

 javac ImportKey.java
 java ImportKey key.der cert.der

  - arg1 is your key and arg2 iscertificate.

Commands will put your keys to Java Key Store.

Phani
  • 5,319
  • 6
  • 35
  • 43
  • I'm familiar with the ImportKey.java file. I have no idea which one of the 3 .der files represents the key and/or cert. So I tried every possible combination: `java ImportKey 1.der 2.der` `java ImportKey 1.der 3.der` `java ImportKey 2.der 1.der` `java ImportKey 2.der 3.der` `java ImportKey 3.der 1.der` `java ImportKey 3.der 2.der` All these command resulted in one of the following errors: java.security.InvalidKeyException: IOException : DER input, Integer tag error or java.security.InvalidKeyException: invalid key format – B.T. Apr 12 '12 at 10:21
  • You could talk to the person who provided the files to find out which one is a certificate and key. – Phani Apr 12 '12 at 10:26
  • I am now sure which of the .der files is the key and which is cert. If I run the ImportKey tool, I still receive: java.security.InvalidKeyException: invalid key format – B.T. Apr 12 '12 at 12:00
  • After debugging the ImportKey class, it fails on the following line: `PKCS8EncodedKeySpec keysp = new PKCS8EncodedKeySpec ( key );` `PrivateKey ff = kf.generatePrivate (keysp);` – B.T. Apr 12 '12 at 12:34
  • Please run this command and check if file is valid: openssl x509 -inform der -in certificate_file -text – Phani Apr 12 '12 at 12:49
  • openssl x509 -inform der -in mykey.der -text ==> unable to load certificate 2144:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:.\crypto\as n1\tasn_dec.c:1316: 2144:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:.\ crypto\asn1\tasn_dec.c:380:Type=X509 – B.T. Apr 12 '12 at 13:21
  • the above command should display the text of the der file. So if it cannot read, it's not a valid file. Please check with administrator – Phani Apr 12 '12 at 13:22
  • @B.T. Are the certificates generated from Linux and porting to Windows? The same issue reported here with same error. http://serverfault.com/questions/316907/ssl-error-unable-to-read-server-certificate-from-file – Phani Apr 12 '12 at 13:32
  • I've checked the content of the files and they seem ok, (line 2): `MIIE7jCCA9agAwIBAgIQQTLhnGCtyKJ6XSvuO0KjejANBgkqhkiG9w0BAQUFADCB`. EDIT: If i try with PEM instead of DER I can see the content... – B.T. Apr 12 '12 at 13:35
  • @B.T. I'm pretty sure the file is not in proper .der format, or openssl is not able to parse it. Even most of the links suggest the same. http://rt.openssl.org/Ticket/Display.html?id=2007&user=guest&pass=guest – Phani Apr 12 '12 at 13:40