How to convert .pfx file to keystore with private key?
Asked Answered
V

7

142

I need to sign Android application (.apk).
I have .pfx file. I converted it to .cer file via Internet Explorer and then converted .cer to .keystore using keytool. Then I've tried to sign .apk with jarsigner but it says that .keystore doesn't content a private key.

What I'm doing wrong?

Varuna answered 18/11, 2010 at 16:25 Comment(1)
This can be useful: how can I find and run the keytool for Windows #5488839Swindell
P
327

Using JDK 1.6 or later

It has been pointed out by Justin in the comments below that keytool alone is capable of doing this using the following command (although only in JDK 1.6 and later):

keytool -importkeystore -srckeystore mypfxfile.pfx -srcstoretype pkcs12 
-destkeystore clientcert.jks -deststoretype JKS

Using JDK 1.5 or below

OpenSSL can do it all. This answer on JGuru is the best method that I've found so far.

Firstly make sure that you have OpenSSL installed. Many operating systems already have it installed as I found with Mac OS X.

The following two commands convert the pfx file to a format that can be opened as a Java PKCS12 key store:

openssl pkcs12 -in mypfxfile.pfx -out mypemfile.pem
openssl pkcs12 -export -in mypemfile.pem -out mykeystore.p12 -name "MyCert"

NOTE that the name provided in the second command is the alias of your key in the new key store.

You can verify the contents of the key store using the Java keytool utility with the following command:

keytool -v -list -keystore mykeystore.p12 -storetype pkcs12

Finally if you need to you can convert this to a JKS key store by importing the key store created above into a new key store:

keytool -importkeystore -srckeystore mykeystore.p12 -destkeystore clientcert.jks -srcstoretype pkcs12 -deststoretype JKS
Purpose answered 17/1, 2011 at 14:11 Comment(10)
there is no need for all three steps, just run: keytool -importkeystore -srckeystore mykeystore.pxf -destkeystore clientcert.jks -srcstoretype pkcs12 -deststoretype JKSWehner
I think that the older versions of keytool wouldn't let you do it. I remember that 8 years ago I'd have to run openssl but now with keytool in the Oracle JDK 6 and 7, it works like a charm, just like Justin said.Joleenjolene
Please note I gave that answer in a simpler form with more detail a year before Justin.Conflux
@Conflux Noted. Your answer is very complete and deserves lots of up votes :)Purpose
This really is a great answer and it saved me after days of research. This answer really deserves many more upvotes. Thank you sir.Slater
@Slater Thank you very much. I'm glad that it helped. I never realized that the problem was this common when I posted my answer.Purpose
I tried the first solution on JDK 7 and 8 on OS X 10.12 and Windows 2012 R2. It did not produce a functional file for use. However, when I used the openssl commands the result was fine.Ferdinandferdinanda
I have a question about the method using JDK 1.6+. Does clientcert.jks have to exist before running the command, or does it get created by the command? In otherwords, does this command convert the pfx to a new jks store or does it import it into an existing jks keystoreFrightful
@bahaa It's been a while since I looked but I'm pretty sure that it creates a new key storePurpose
Ok, this may be obvious for most people. But let me add my comment for people like me. This command is to run on Terminal if you're on Mac.Strained
C
34

I found this page which tells you how to import a PFX to JKS (Java Key Store):

keytool -importkeystore -srckeystore PFX_P12_FILE_NAME -srcstoretype pkcs12 
-srcstorepass PFX_P12_FILE -srcalias SOURCE_ALIAS -destkeystore KEYSTORE_FILE 
-deststoretype jks -deststorepass PASSWORD -destalias ALIAS_NAME
Chassepot answered 19/7, 2012 at 23:56 Comment(2)
I have one problem, the pfx doesn't have a password, so -srcstorepass is my problem. This PFX is created by a LetsEncrypt client for WindowsKozak
@Kozak , similar missing PFX password issue here. This worked for me: ... -srcstorepass "" ...Iolite
C
28

jarsigner can use your pfx file as the keystore for signing your jar. Be sure that your pfx file has the private key and the cert chain when you export it. There is no need to convert to other formats. The trick is to obtain the Alias of your pfx file:

 keytool -list -storetype pkcs12 -keystore your_pfx_file -v | grep Alias

Once you have your alias, signing is easy

jarsigner.exe -storetype pkcs12 -keystore pfx_file jar_file "your alias"

The above two commands will prompt you for the password you specified at pfx export. If you want to have your password hang out in clear text use the -storepass switch before the -keystore switch

Once signed, admire your work:

jarsigner.exe -verify -verbose -certs  yourjarfile
Conflux answered 4/5, 2011 at 16:49 Comment(1)
+1 for not having to convert the keystore file (I have it in enough formats already!)Trixy
A
2

Justin(above) is accurate. However, keep in mind that depending on who you get the certificate from (intermediate CA, root CA involved or not) or how the pfx is created/exported, sometimes they could be missing the certificate chain. After Import, You would have a certificate of PrivateKeyEntry type, but with a chain of length of 1.

To fix this, there are several options. The easier option in my mind is to import and export the pfx file in IE(choosing the option of Including all the certificates in the chain). The import and export process of certificates in IE should be very easy and well documented elsewhere.

Once exported, import the keystore as Justin pointed above. Now, you would have a keystore with certificate of type PrivateKeyEntry and with a certificate chain length of more than 1.

Certain .Net based Web service clients error out(unable to establish trust relationship), if you don't do the above.

Argentum answered 7/2, 2014 at 22:50 Comment(1)
This doesn't seem to work on IE11. It's failing to included the certificate chain even though I'm telling it to. I know this has worked in the past though.Saccharase
U
1

Your PFX file should contain the private key within it. Export the private key and certificate directly from your PFX file (e.g. using OpenSSL) and import them into your Java keystore.

Edit

Further information:

  • Download OpenSSL for Windows here.
  • Export private key: openssl pkcs12 -in filename.pfx -nocerts -out key.pem
  • Export certificate: openssl pkcs12 -in filename.pfx -clcerts -nokeys -out cert.pem
  • Import private key and certificate into Java keystore using keytool.
Unquote answered 18/11, 2010 at 16:37 Comment(2)
could you please tell me how can i import key.pem and cert.pem using keytool ?Exploitation
Small addition : you have to add -nodes in the end when exporting private kyBrimmer
K
0

If you work with JDK 1.5 or below the keytool utility will not have the -importkeystore option (see JDK 1.5 keytool documentation) and the solution by MikeD will be available only by transferring the .pfx on a machine with a newer JDK (1.6 or above).

Another option in JDK 1.5 or below (if you have Oracle WebLogic product), is to follow the instructions from this Oracle document: Using PFX and PEM Certificate Formats with Keystores. It describes the conversion into .pem format, how to extract certificates information from this textual format, and import it into .jks format with java utils.ImportPrivateKey utility (this is an utility included with WebLogic product).

Knowlton answered 13/10, 2013 at 13:16 Comment(0)
T
0

This is my solution for a Visual Studio/Xamarin environment.

Intended outcomes:

  • The PFX (foo.pfx in the examples) will be imported into JKS keystore (bar.keystore in the examples).
  • The keystore will be protected with a new password (shall be referred to as "signing password").
  • The keystore will contain a single key.
  • The single key will have an alias whose name matches that of the keystore (bar in the examples).
  • The single key will be protected with the signing password.
  • The Xamarin tooling will be able to use the keystore to easily sign apps.

Note that it is not necessary for the names and passwords to match, but this is common practice, as well as what the tooling expects.

keytool location: %JAVA_HOME%\bin, e.g.:

  • C:\Program Files\Android\jdk\microsoft_dist_openjdk_1.8.0.25\bin
  • C:\Program Files (x86)\Java\jre1.8.0_331\bin

Steps:

  1. Obtain internally-signed PFX. PFX will have temporarily assigned password.
  2. Import JKS keystore from PFX; when prompted, supply signing password twice for destination keystore password, and supply temporarily assigned password for source keystore password.
    keytool -importkeystore -srckeystore foo.pfx -srcstoretype pkcs12 -destkeystore bar.keystore -deststoretype JKS
    
    Generated JKS keystore will have a single key alias "1" with same temporarily assigned password as PFX from step 1.
  3. Change key alias to match keystore name; when prompted, supply signing password for keystore password, and temporarily assigned password for key password.
    keytool -changealias -alias 1 -destalias bar -keystore bar.keystore
    
  4. Change key password to signing password; when prompted, supply signing password for keystore password, temporarily assigned password for old key password, and signing password twice for new key password.
    keytool -keypasswd -keystore bar.keystore -alias bar
    
  5. Ensure finished keystore is located at the following path, or similar per your installation:
    %LOCALAPPDATA%\Xamarin\Mono for Android\Keystore\bar\bar.keystore
    

Verify content:

  1. View contents of original PFX; when prompted, supply temporarily assigned password for keystore password.
    keytool -list -v -keystore foo.pfx -storetype pkcs12
    
  2. View contents of generated keystore; when prompted, supply signing password for keystore password.
    keytool -list -v -keystore bar.keystore
    
  3. Compare output from steps 1 and 2 (e.g. save to text file and perform file diff). Content should be identical (i.e. certificate chains, fingerprints, etc.; header and footer text will differ).

You should now be able to see and use the imported keystore when using the Ad-Hoc distribution option in Visual Studio. Provide the signing password when prompted.

Tellurion answered 14/6, 2022 at 14:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.