Skip to content

Commit f77a658

Browse files
committed
8153005: Upgrade the default PKCS12 encryption/MAC algorithms
Reviewed-by: mullan
1 parent 8a065ef commit f77a658

File tree

8 files changed

+398
-339
lines changed

8 files changed

+398
-339
lines changed

src/java.base/share/classes/sun/security/pkcs12/PKCS12KeyStore.java

Lines changed: 66 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import javax.security.auth.DestroyFailedException;
6666
import javax.security.auth.x500.X500Principal;
6767

68+
import sun.security.action.GetPropertyAction;
6869
import sun.security.tools.KeyStoreUtil;
6970
import sun.security.util.*;
7071
import sun.security.pkcs.ContentInfo;
@@ -79,48 +80,10 @@
7980
* Implements the PKCS#12 PFX protected using the Password privacy mode.
8081
* The contents are protected using Password integrity mode.
8182
*
82-
* Currently these PBE algorithms are used by default:
83-
* - PBEWithSHA1AndDESede to encrypt private keys, iteration count 50000.
84-
* - PBEWithSHA1AndRC2_40 to encrypt certificates, iteration count 50000.
85-
*
86-
* The default Mac algorithm is HmacPBESHA1, iteration count 100000.
87-
*
88-
* Supported encryption of various implementations :
89-
*
90-
* Software and mode. Certificate encryption Private key encryption
91-
* ---------------------------------------------------------------------
92-
* MSIE4 (domestic 40 bit RC2. 40 bit RC2
93-
* and xport versions)
94-
* PKCS#12 export.
95-
*
96-
* MSIE4, 5 (domestic 40 bit RC2, 40 bit RC2,
97-
* and export versions) 3 key triple DES 3 key triple DES
98-
* PKCS#12 import.
99-
*
100-
* MSIE5 40 bit RC2 3 key triple DES,
101-
* PKCS#12 export. with SHA1 (168 bits)
102-
*
103-
* Netscape Communicator 40 bit RC2 3 key triple DES,
104-
* (domestic and export with SHA1 (168 bits)
105-
* versions) PKCS#12 export
106-
*
107-
* Netscape Communicator 40 bit ciphers only All.
108-
* (export version)
109-
* PKCS#12 import.
110-
*
111-
* Netscape Communicator All. All.
112-
* (domestic or fortified
113-
* version) PKCS#12 import.
114-
*
115-
* OpenSSL PKCS#12 code. All. All.
116-
* ---------------------------------------------------------------------
117-
*
118-
* NOTE: PKCS12 KeyStore supports PrivateKeyEntry and TrustedCertficateEntry.
119-
* PKCS#12 is mainly used to deliver private keys with their associated
120-
* certificate chain and aliases. In a PKCS12 keystore, entries are
121-
* identified by the alias, and a localKeyId is required to match the
122-
* private key with the certificate. Trusted certificate entries are identified
123-
* by the presence of an trustedKeyUsage attribute.
83+
* NOTE: In a PKCS12 keystore, entries are identified by the alias, and
84+
* a localKeyId is required to match the private key with the certificate.
85+
* Trusted certificate entries are identified by the presence of an
86+
* trustedKeyUsage attribute.
12487
*
12588
* @author Seema Malkani
12689
* @author Jeff Nisewanger
@@ -130,6 +93,32 @@
13093
*/
13194
public final class PKCS12KeyStore extends KeyStoreSpi {
13295

96+
// Hardcoded defaults. They should be the same with commented out
97+
// lines inside the java.security file.
98+
private static final String DEFAULT_CERT_PBE_ALGORITHM
99+
= "PBEWithHmacSHA256AndAES_256";
100+
private static final String DEFAULT_KEY_PBE_ALGORITHM
101+
= "PBEWithHmacSHA256AndAES_256";
102+
private static final String DEFAULT_MAC_ALGORITHM = "HmacPBESHA256";
103+
private static final int DEFAULT_CERT_PBE_ITERATION_COUNT = 10000;
104+
private static final int DEFAULT_KEY_PBE_ITERATION_COUNT = 10000;
105+
private static final int DEFAULT_MAC_ITERATION_COUNT = 10000;
106+
107+
// Legacy settings. Used when "keystore.pkcs12.legacy" is set.
108+
private static final String LEGACY_CERT_PBE_ALGORITHM
109+
= "PBEWithSHA1AndRC2_40";
110+
private static final String LEGACY_KEY_PBE_ALGORITHM
111+
= "PBEWithSHA1AndDESede";
112+
private static final String LEGACY_MAC_ALGORITHM = "HmacPBESHA1";
113+
private static final int LEGACY_PBE_ITERATION_COUNT = 50000;
114+
private static final int LEGACY_MAC_ITERATION_COUNT = 100000;
115+
116+
// Big switch. When this system property is set. Legacy settings
117+
// are used no matter what other keystore.pkcs12.* properties are set.
118+
// Note: This is only a system property, there's no same-name
119+
// security property defined.
120+
private static final String USE_LEGACY_PROP = "keystore.pkcs12.legacy";
121+
133122
// special PKCS12 keystore that supports PKCS12 and JKS file formats
134123
public static final class DualFormatPKCS12 extends KeyStoreDelegator {
135124
public DualFormatPKCS12() {
@@ -845,9 +834,6 @@ private SecretKey getPBEKey(char[] password) throws IOException
845834
* Encrypt private key or secret key using Password-based encryption (PBE)
846835
* as defined in PKCS#5.
847836
*
848-
* NOTE: By default, pbeWithSHAAnd3-KeyTripleDES-CBC algorithmID is
849-
* used to derive the key and IV.
850-
*
851837
* @return encrypted private key or secret key encoded as
852838
* EncryptedPrivateKeyInfo
853839
*/
@@ -1866,9 +1852,6 @@ private byte[] createSafeContent()
18661852
* Encrypt the contents using Password-based (PBE) encryption
18671853
* as defined in PKCS #5.
18681854
*
1869-
* NOTE: Currently pbeWithSHAAnd40BiteRC2-CBC algorithmID is used
1870-
* to derive the key and IV.
1871-
*
18721855
* @return encrypted contents encoded as EncryptedContentInfo
18731856
*/
18741857
private byte[] encryptContent(byte[] data, char[] password)
@@ -2640,25 +2623,42 @@ public boolean engineProbe(InputStream stream) throws IOException {
26402623
return result;
26412624
}
26422625

2643-
// 8076190: Customizing the generation of a PKCS12 keystore
2626+
// The following methods are related to customizing
2627+
// the generation of a PKCS12 keystore or private/secret
2628+
// key entries.
2629+
2630+
private static boolean useLegacy() {
2631+
return GetPropertyAction.privilegedGetProperty(
2632+
USE_LEGACY_PROP) != null;
2633+
}
26442634

26452635
private static String defaultCertProtectionAlgorithm() {
2636+
if (useLegacy()) {
2637+
return LEGACY_CERT_PBE_ALGORITHM;
2638+
}
26462639
String result = SecurityProperties.privilegedGetOverridable(
26472640
"keystore.pkcs12.certProtectionAlgorithm");
26482641
return (result != null && !result.isEmpty())
2649-
? result : "PBEWithSHA1AndRC2_40";
2642+
? result : DEFAULT_CERT_PBE_ALGORITHM;
26502643
}
26512644

26522645
private static int defaultCertPbeIterationCount() {
2646+
if (useLegacy()) {
2647+
return LEGACY_PBE_ITERATION_COUNT;
2648+
}
26532649
String result = SecurityProperties.privilegedGetOverridable(
26542650
"keystore.pkcs12.certPbeIterationCount");
26552651
return (result != null && !result.isEmpty())
2656-
? string2IC("certPbeIterationCount", result) : 50000;
2652+
? string2IC("certPbeIterationCount", result)
2653+
: DEFAULT_CERT_PBE_ITERATION_COUNT;
26572654
}
26582655

26592656
// Read both "keystore.pkcs12.keyProtectionAlgorithm" and
26602657
// "keystore.PKCS12.keyProtectionAlgorithm" for compatibility.
26612658
private static String defaultKeyProtectionAlgorithm() {
2659+
if (useLegacy()) {
2660+
return LEGACY_KEY_PBE_ALGORITHM;
2661+
}
26622662
String result = AccessController.doPrivileged(new PrivilegedAction<String>() {
26632663
public String run() {
26642664
String result;
@@ -2680,28 +2680,39 @@ public String run() {
26802680
}
26812681
});
26822682
return (result != null && !result.isEmpty())
2683-
? result : "PBEWithSHA1AndDESede";
2683+
? result : DEFAULT_KEY_PBE_ALGORITHM;
26842684
}
26852685

26862686
private static int defaultKeyPbeIterationCount() {
2687+
if (useLegacy()) {
2688+
return LEGACY_PBE_ITERATION_COUNT;
2689+
}
26872690
String result = SecurityProperties.privilegedGetOverridable(
26882691
"keystore.pkcs12.keyPbeIterationCount");
26892692
return (result != null && !result.isEmpty())
2690-
? string2IC("keyPbeIterationCount", result) : 50000;
2693+
? string2IC("keyPbeIterationCount", result)
2694+
: DEFAULT_KEY_PBE_ITERATION_COUNT;
26912695
}
26922696

26932697
private static String defaultMacAlgorithm() {
2698+
if (useLegacy()) {
2699+
return LEGACY_MAC_ALGORITHM;
2700+
}
26942701
String result = SecurityProperties.privilegedGetOverridable(
26952702
"keystore.pkcs12.macAlgorithm");
26962703
return (result != null && !result.isEmpty())
2697-
? result : "HmacPBESHA1";
2704+
? result : DEFAULT_MAC_ALGORITHM;
26982705
}
26992706

27002707
private static int defaultMacIterationCount() {
2708+
if (useLegacy()) {
2709+
return LEGACY_MAC_ITERATION_COUNT;
2710+
}
27012711
String result = SecurityProperties.privilegedGetOverridable(
27022712
"keystore.pkcs12.macIterationCount");
27032713
return (result != null && !result.isEmpty())
2704-
? string2IC("macIterationCount", result) : 100000;
2714+
? string2IC("macIterationCount", result)
2715+
: DEFAULT_MAC_ITERATION_COUNT;
27052716
}
27062717

27072718
private static int string2IC(String type, String value) {

src/java.base/share/conf/security/java.security

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,33 +1144,33 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep
11441144
# The algorithm used to encrypt a certificate. This can be any non-Hmac PBE
11451145
# algorithm defined in the Cipher section of the Java Security Standard
11461146
# Algorithm Names Specification. When set to "NONE", the certificate
1147-
# is not encrypted. The default value is "PBEWithSHA1AndRC2_40".
1148-
#keystore.pkcs12.certProtectionAlgorithm = PBEWithSHA1AndRC2_40
1147+
# is not encrypted. The default value is "PBEWithHmacSHA256AndAES_256".
1148+
#keystore.pkcs12.certProtectionAlgorithm = PBEWithHmacSHA256AndAES_256
11491149

11501150
# The iteration count used by the PBE algorithm when encrypting a certificate.
1151-
# This value must be a positive integer. The default value is 50000.
1152-
#keystore.pkcs12.certPbeIterationCount = 50000
1151+
# This value must be a positive integer. The default value is 10000.
1152+
#keystore.pkcs12.certPbeIterationCount = 10000
11531153

11541154
# The algorithm used to encrypt a private key or secret key. This can be
11551155
# any non-Hmac PBE algorithm defined in the Cipher section of the Java
11561156
# Security Standard Algorithm Names Specification. The value must not be "NONE".
1157-
# The default value is "PBEWithSHA1AndDESede".
1158-
#keystore.pkcs12.keyProtectionAlgorithm = PBEWithSHA1AndDESede
1157+
# The default value is "PBEWithHmacSHA256AndAES_256".
1158+
#keystore.pkcs12.keyProtectionAlgorithm = PBEWithHmacSHA256AndAES_256
11591159

11601160
# The iteration count used by the PBE algorithm when encrypting a private key
11611161
# or a secret key. This value must be a positive integer. The default value
1162-
# is 50000.
1163-
#keystore.pkcs12.keyPbeIterationCount = 50000
1162+
# is 10000.
1163+
#keystore.pkcs12.keyPbeIterationCount = 10000
11641164

11651165
# The algorithm used to calculate the optional MacData at the end of a PKCS12
11661166
# file. This can be any HmacPBE algorithm defined in the Mac section of the
11671167
# Java Security Standard Algorithm Names Specification. When set to "NONE",
1168-
# no Mac is generated. The default value is "HmacPBESHA1".
1169-
#keystore.pkcs12.macAlgorithm = HmacPBESHA1
1168+
# no Mac is generated. The default value is "HmacPBESHA256".
1169+
#keystore.pkcs12.macAlgorithm = HmacPBESHA256
11701170

11711171
# The iteration count used by the MacData algorithm. This value must be a
1172-
# positive integer. The default value is 100000.
1173-
#keystore.pkcs12.macIterationCount = 100000
1172+
# positive integer. The default value is 10000.
1173+
#keystore.pkcs12.macIterationCount = 10000
11741174

11751175
#
11761176
# Enhanced exception message information
@@ -1308,4 +1308,4 @@ jdk.io.permissionsUseCanonicalPath=false
13081308
# properties. In the case that both properties are simultaneously set, the
13091309
# System value prevails. The default value of the property is "false".
13101310
#
1311-
#jdk.security.allowNonCaAnchor=true
1311+
#jdk.security.allowNonCaAnchor=true

test/jdk/sun/security/mscapi/VeryLongAlias.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
2323

2424
/*
2525
* @test
26-
* @bug 8223063
26+
* @bug 8223063 8153005
2727
* @requires os.family == "windows"
2828
* @library /test/lib
2929
* @summary Support CNG RSA keys
@@ -48,7 +48,11 @@ public class VeryLongAlias {
4848

4949
public static void main(String[] args) throws Throwable {
5050

51-
SecurityTools.keytool("-genkeypair -storetype pkcs12 -keystore ks"
51+
// Using the old algorithms to make sure the file is recognized
52+
// by the certutil command on old versions of Windows.
53+
SecurityTools.keytool(
54+
"-J-Dkeystore.pkcs12.legacy"
55+
+ " -genkeypair -storetype pkcs12 -keystore ks"
5256
+ " -storepass changeit -keyalg RSA -dname CN=A -alias "
5357
+ alias);
5458
String id = ((X509Certificate)KeyStore.getInstance(

0 commit comments

Comments
 (0)