Can't change the keystore format
Asked Answered
T

2

16

I'm trying to make some keystores using keytool from the latest JRE (version 1.8.0_151). When I create the keystore using this command keytool -genkey -alias serverprivate -keystore server.private -keyalg rsa -storepass apassword -keypass apassword it shows me this warning:

Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate 
to  PKCS12 which is an industry standard format using "keytool 
-importkeystore -srckeystore server.private -destkeystore server.private
-deststoretype pkcs12".

So I type the command, and it says it's done and the old keystore was saved in server.private_old. But when I run keytool -list -keystore server.private and type the password, it is still listed as JKS instead of PKCS12. Why is this?

update
It's not silently changed to pkcs12 either, because when I use KeyStore store = KeyStore.getInstance("pkcs12"); in java it throws an error, while it works fine when using getInstance("JKS");

update 2
And when using keytool -genkey -alias serverprivate -keystore server.private -storetype PKCS12 -keyalg rsa it doesn't show me a warning, but still shows as a JKS keystore when using keytool -list server.private.

Tapir answered 4/12, 2017 at 17:37 Comment(12)
Could you try saving to a different file name and see what happens? If you're on a Unix system, could you also try file <keystore_name.ext> as well? Hmm, that last sentence was deprecated before I could type it with the update :)Cesar
I'd strongly recommend to use the .jks and .p12 file name extensions, by the way.Cesar
@MaartenBodewes still listed as JKS, also when changing extension to p12Tapir
OK, this is starting to look like a bug. Note that Java 9 uses .p12 as default, so it could be an issue backporting. But could you move your -deststoretype arguments to the start of the command, just to be sure? What kind of contents are in the keystore, anything maybe that Java 8 doesn't support such as private keys without certificates?Cesar
New command is keytool -deststoretype pkcs12 -importkeystore -srckeystore server.private -destkeystore newserver.p12, running keytool -list -keystore newserver.p12 still shows a JKS format.Tapir
Did you add security / cryptography providers? Or are you using a vanilla Java SE environment?Cesar
Completely vanillaTapir
@MaartenBodewes Another weird thing; when generating the keystore without the -storetype parameter, it apparently defaults to JKS. It shows me the warning immediately after generating, and when using keytool -list -keystore server.private it shows up at the bottom of the info. But when generating it with -storetype PKCS12, it doesn't show a warning, but the weird thing is it also doesn't show a warning at the bottom of the info.Tapir
The new keystore really is PKCS12. The bug is that keytool says it's jks. To verify this you can parse it with openssl: openssl pkcs12 -in server.privateJudiejudith
@JamesKPolk But in java I can only use it as JKS format, pkcs12 throws an errorTapir
Well, it works for me. Make sure you have the correct password supplied to KeyStore.load(...).Judiejudith
From the redhat page: Warning: The JCEKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 ... message can be all and safely ignored. There will be no impact for not changing the JCEKS keystore format, and it is even not recommended to change or migrate it.Havener
J
9

It seems to be a bug in what keytool displays rather than what it does. Consider the following experiments.

(EDIT: bug report filed)

First, my jdk version is 1.8.0_152:

excalibur:~ ronan$ java -version
java version "1.8.0_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)

Now, create the keystore as you specified:

excalibur:~ ronan$ keytool -genkey -alias serverprivate -keystore server.private -keyalg rsa -storepass apassword -keypass apassword
What is your first and last name?
  [Unknown]:  Art Vandelay
What is the name of your organizational unit?
  [Unknown]:  Export/Import
What is the name of your organization?
  [Unknown]:  Vandelay Industries
What is the name of your City or Locality?
  [Unknown]:  New York
What is the name of your State or Province?
  [Unknown]:  New York
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=Art Vandelay, OU=Export/Import, O=Vandelay Industries, L=New York, ST=New York, C=US correct?
  [no]:  yes


Warning:
The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore server.private -destkeystore server.private -deststoretype pkcs12".

Now, following the instructions given:

excalibur:~ ronan$ keytool -importkeystore -srckeystore server.private -destkeystore server.private -deststoretype pkcs12
Enter source keystore password:  
Entry for alias serverprivate successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

Warning:
Migrated "server.private" to Non JKS/JCEKS. The JKS keystore is backed up as "server.private.old".

But when we list it with keytool it still says JKS.

excalibur:~ ronan$ keytool -list -keystore server.private
Enter keystore password:  
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

serverprivate, Dec 4, 2017, PrivateKeyEntry, 
Certificate fingerprint (SHA1): 16:E8:C6:12:7A:F1:7A:B8:64:98:EC:12:C4:07:9E:67:06:BD:DD:BD

However, openssl can parse it as pkcs12 just fine.

excalibur:~ ronan$ openssl pkcs12 -in server.private
Enter Import Password:
MAC verified OK
Bag Attributes
    friendlyName: serverprivate
    localKeyID: 54 69 6D 65 20 31 35 31 32 34 31 33 32 30 38 31 38 32 
Key Attributes: <No Attributes>
Enter PEM pass phrase:
Bag Attributes
    friendlyName: serverprivate
    localKeyID: 54 69 6D 65 20 31 35 31 32 34 31 33 32 30 38 31 38 32 
subject=/C=US/ST=New York/L=New York/O=Vandelay Industries/OU=Export/Import/CN=Art Vandelay
issuer=/C=US/ST=New York/L=New York/O=Vandelay Industries/OU=Export/Import/CN=Art Vandelay
-----BEGIN CERTIFICATE-----
MIIDoTCCAomgAwIBAgIEKSoRITANBgkqhkiG9w0BAQsFADCBgDELMAkGA1UEBhMC
VVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcgWW9yazEcMBoGA1UE
ChMTVmFuZGVsYXkgSW5kdXN0cmllczEWMBQGA1UECxMNRXhwb3J0L0ltcG9ydDEV
MBMGA1UEAxMMQXJ0IFZhbmRlbGF5MB4XDTE3MTIwNDE4NDM1NVoXDTE4MDMwNDE4
NDM1NVowgYAxCzAJBgNVBAYTAlVTMREwDwYDVQQIEwhOZXcgWW9yazERMA8GA1UE
BxMITmV3IFlvcmsxHDAaBgNVBAoTE1ZhbmRlbGF5IEluZHVzdHJpZXMxFjAUBgNV
BAsTDUV4cG9ydC9JbXBvcnQxFTATBgNVBAMTDEFydCBWYW5kZWxheTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAIwVIy24Hws6ffaEQGhYEyaw2JC4UPLH
wtSXpJaZf3lrdtbktbLC+zKJ93fFVfoukX5vpnZKxv+f724duAszkVWN3bBrnAwb
6sh445tXiRhT2eS+z0rHtXwiPWUKOAPOxGUP1Lhfl5ZCPR4bmohyh/daSX1ppT3P
k6//lf1y2RdsS5hZ5Ltx9dr99/txsv4a1D8uuPDHIf8dvWfOqGb7ywIAlrbh5JsA
4IWjMVFMpDQ2WM/C+v48y2W7AdgxGD0J/nNC6t4QfAgwhvVyXbiu9IbAR+ivn59E
VqC83qv4bBkffB3yYk6WSHSl7YloJueWalVAoudf4uHeaNZBLCvbNsMCAwEAAaMh
MB8wHQYDVR0OBBYEFNOc6gJkUFCSgyHCDFGJmZwtPLgIMA0GCSqGSIb3DQEBCwUA
A4IBAQAVyc6j9U+va5U02MxsjDE6LWDPg+0FaqpTAQlU6xhVrZlKWuX+Dup4PF6S
s4oqhInb7XcGOjbLkVTnuEY5mwfHnyGqNhmyyUwJOVrWZJWBZADvhdcZi0w/jclg
jAb7dP1VssR4Ozgsd1XkGxnS7P8e344xpjQd1krPc1Od7qhFSF6FufTDvgEcrmx/
qrHpLpwoYPTyuv+NtD+7KlWINqWq5PT1olydd6ki8O+bTsgDuy8rnvqd/jJ7dsuv
VLNc+IDEEMO26hS8d1WkppTTuLrayE07LCV8df68WHv6KumDSc5Mb0zOUdLqZUDQ
Wmxbt0kEAAG6jgbpACBpGEqtAtTs
-----END CERTIFICATE-----

and the following Java snippet can also parse it.

import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.Collections;

public class Main {
    public static void main(String[] args) throws Exception {
        KeyStore pkcs12 = KeyStore.getInstance("PKCS12");
        pkcs12.load(new FileInputStream("../../../server.private"), "apassword".toCharArray());
        for (String alias : Collections.list(pkcs12.aliases())) {
            System.out.println(alias);
        }
    }
}

and the output is

serverprivate

Judiejudith answered 4/12, 2017 at 18:53 Comment(4)
I get the same (misleading) result by default, but more accurate type indications from keytool if I turn off keystore.type.compat in JRE/lib/security/java.security . Also a very subtle distinguisher even with the compat kludge on: if I keystore -list and hit return when prompted for storepass, for JKS the list includes cert fingerprint(s) but for P12 it doesn't, because JKS stores certs in clear but most implementations of P12 including JCE 'encrypt' the certbag with easily-broken RC2-40 (which is silly but everyone does it).Litt
My initial comment below the question indicated the file command that is included in most Posix systems (linux, apple, cygwin etc.) which you also could use to verify the file type. Great to know, look for bug report tomorrow.Cesar
I recently took a look at this again, but when I call pkcs12.load() it throws this error: java.io.IOException: DerInputStream.getLength(): lengthTag=109, too big., while it works fine when I use KeyStore.getInstance("JKS");Tapir
How to update the keystore to 2048 in android. I have a weak keyGarnes
A
1

The above problem is solved follow this link for the steps

https://docs.flutter.dev/deployment/android#create-an-upload-keystore

it contains the updated steps...

After running the

keytool -genkey -v -keystore c:\Users\USER_NAME\upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias upload

I get this command as a part of warning message.

keytool -importkeystore -srckeystore c:\Users\USER_NAME\upload-keystore.jks -destkeystore c:\Users\USER_NAME\upload-keystore.jks -deststoretype pkcs12

and this is the following output after running the above command.

Enter source keystore password:
Entry for alias upload successfully imported.
Import command completed:  1 entries successfully imported, 0 entries failed or cancelled

Warning:
Migrated "c:\Users\USER_NAME\upload-keystore.jks" to PKCS12. The JKS keystore is backed up as "c:\Users\USER_NAME\upload-keystore.jks.old".
Arum answered 4/1, 2022 at 13:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.