8153005: Upgrade the default PKCS12 encryption/MAC algorithms

Reviewed-by: mullan
This commit is contained in:
Weijun Wang 2020-10-30 13:23:33 +00:00
parent 8a065ef2e2
commit f77a658557
8 changed files with 399 additions and 340 deletions

View file

@ -65,6 +65,7 @@ import javax.crypto.Mac;
import javax.security.auth.DestroyFailedException;
import javax.security.auth.x500.X500Principal;
import sun.security.action.GetPropertyAction;
import sun.security.tools.KeyStoreUtil;
import sun.security.util.*;
import sun.security.pkcs.ContentInfo;
@ -79,48 +80,10 @@ import sun.security.x509.AuthorityKeyIdentifierExtension;
* Implements the PKCS#12 PFX protected using the Password privacy mode.
* The contents are protected using Password integrity mode.
*
* Currently these PBE algorithms are used by default:
* - PBEWithSHA1AndDESede to encrypt private keys, iteration count 50000.
* - PBEWithSHA1AndRC2_40 to encrypt certificates, iteration count 50000.
*
* The default Mac algorithm is HmacPBESHA1, iteration count 100000.
*
* Supported encryption of various implementations :
*
* Software and mode. Certificate encryption Private key encryption
* ---------------------------------------------------------------------
* MSIE4 (domestic 40 bit RC2. 40 bit RC2
* and xport versions)
* PKCS#12 export.
*
* MSIE4, 5 (domestic 40 bit RC2, 40 bit RC2,
* and export versions) 3 key triple DES 3 key triple DES
* PKCS#12 import.
*
* MSIE5 40 bit RC2 3 key triple DES,
* PKCS#12 export. with SHA1 (168 bits)
*
* Netscape Communicator 40 bit RC2 3 key triple DES,
* (domestic and export with SHA1 (168 bits)
* versions) PKCS#12 export
*
* Netscape Communicator 40 bit ciphers only All.
* (export version)
* PKCS#12 import.
*
* Netscape Communicator All. All.
* (domestic or fortified
* version) PKCS#12 import.
*
* OpenSSL PKCS#12 code. All. All.
* ---------------------------------------------------------------------
*
* NOTE: PKCS12 KeyStore supports PrivateKeyEntry and TrustedCertficateEntry.
* PKCS#12 is mainly used to deliver private keys with their associated
* certificate chain and aliases. In a PKCS12 keystore, entries are
* identified by the alias, and a localKeyId is required to match the
* private key with the certificate. Trusted certificate entries are identified
* by the presence of an trustedKeyUsage attribute.
* NOTE: In a PKCS12 keystore, entries are identified by the alias, and
* a localKeyId is required to match the private key with the certificate.
* Trusted certificate entries are identified by the presence of an
* trustedKeyUsage attribute.
*
* @author Seema Malkani
* @author Jeff Nisewanger
@ -130,6 +93,32 @@ import sun.security.x509.AuthorityKeyIdentifierExtension;
*/
public final class PKCS12KeyStore extends KeyStoreSpi {
// Hardcoded defaults. They should be the same with commented out
// lines inside the java.security file.
private static final String DEFAULT_CERT_PBE_ALGORITHM
= "PBEWithHmacSHA256AndAES_256";
private static final String DEFAULT_KEY_PBE_ALGORITHM
= "PBEWithHmacSHA256AndAES_256";
private static final String DEFAULT_MAC_ALGORITHM = "HmacPBESHA256";
private static final int DEFAULT_CERT_PBE_ITERATION_COUNT = 10000;
private static final int DEFAULT_KEY_PBE_ITERATION_COUNT = 10000;
private static final int DEFAULT_MAC_ITERATION_COUNT = 10000;
// Legacy settings. Used when "keystore.pkcs12.legacy" is set.
private static final String LEGACY_CERT_PBE_ALGORITHM
= "PBEWithSHA1AndRC2_40";
private static final String LEGACY_KEY_PBE_ALGORITHM
= "PBEWithSHA1AndDESede";
private static final String LEGACY_MAC_ALGORITHM = "HmacPBESHA1";
private static final int LEGACY_PBE_ITERATION_COUNT = 50000;
private static final int LEGACY_MAC_ITERATION_COUNT = 100000;
// Big switch. When this system property is set. Legacy settings
// are used no matter what other keystore.pkcs12.* properties are set.
// Note: This is only a system property, there's no same-name
// security property defined.
private static final String USE_LEGACY_PROP = "keystore.pkcs12.legacy";
// special PKCS12 keystore that supports PKCS12 and JKS file formats
public static final class DualFormatPKCS12 extends KeyStoreDelegator {
public DualFormatPKCS12() {
@ -845,9 +834,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
* Encrypt private key or secret key using Password-based encryption (PBE)
* as defined in PKCS#5.
*
* NOTE: By default, pbeWithSHAAnd3-KeyTripleDES-CBC algorithmID is
* used to derive the key and IV.
*
* @return encrypted private key or secret key encoded as
* EncryptedPrivateKeyInfo
*/
@ -1866,9 +1852,6 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
* Encrypt the contents using Password-based (PBE) encryption
* as defined in PKCS #5.
*
* NOTE: Currently pbeWithSHAAnd40BiteRC2-CBC algorithmID is used
* to derive the key and IV.
*
* @return encrypted contents encoded as EncryptedContentInfo
*/
private byte[] encryptContent(byte[] data, char[] password)
@ -2640,25 +2623,42 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
return result;
}
// 8076190: Customizing the generation of a PKCS12 keystore
// The following methods are related to customizing
// the generation of a PKCS12 keystore or private/secret
// key entries.
private static boolean useLegacy() {
return GetPropertyAction.privilegedGetProperty(
USE_LEGACY_PROP) != null;
}
private static String defaultCertProtectionAlgorithm() {
if (useLegacy()) {
return LEGACY_CERT_PBE_ALGORITHM;
}
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.certProtectionAlgorithm");
return (result != null && !result.isEmpty())
? result : "PBEWithSHA1AndRC2_40";
? result : DEFAULT_CERT_PBE_ALGORITHM;
}
private static int defaultCertPbeIterationCount() {
if (useLegacy()) {
return LEGACY_PBE_ITERATION_COUNT;
}
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.certPbeIterationCount");
return (result != null && !result.isEmpty())
? string2IC("certPbeIterationCount", result) : 50000;
? string2IC("certPbeIterationCount", result)
: DEFAULT_CERT_PBE_ITERATION_COUNT;
}
// Read both "keystore.pkcs12.keyProtectionAlgorithm" and
// "keystore.PKCS12.keyProtectionAlgorithm" for compatibility.
private static String defaultKeyProtectionAlgorithm() {
if (useLegacy()) {
return LEGACY_KEY_PBE_ALGORITHM;
}
String result = AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
String result;
@ -2680,28 +2680,39 @@ public final class PKCS12KeyStore extends KeyStoreSpi {
}
});
return (result != null && !result.isEmpty())
? result : "PBEWithSHA1AndDESede";
? result : DEFAULT_KEY_PBE_ALGORITHM;
}
private static int defaultKeyPbeIterationCount() {
if (useLegacy()) {
return LEGACY_PBE_ITERATION_COUNT;
}
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.keyPbeIterationCount");
return (result != null && !result.isEmpty())
? string2IC("keyPbeIterationCount", result) : 50000;
? string2IC("keyPbeIterationCount", result)
: DEFAULT_KEY_PBE_ITERATION_COUNT;
}
private static String defaultMacAlgorithm() {
if (useLegacy()) {
return LEGACY_MAC_ALGORITHM;
}
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.macAlgorithm");
return (result != null && !result.isEmpty())
? result : "HmacPBESHA1";
? result : DEFAULT_MAC_ALGORITHM;
}
private static int defaultMacIterationCount() {
if (useLegacy()) {
return LEGACY_MAC_ITERATION_COUNT;
}
String result = SecurityProperties.privilegedGetOverridable(
"keystore.pkcs12.macIterationCount");
return (result != null && !result.isEmpty())
? string2IC("macIterationCount", result) : 100000;
? string2IC("macIterationCount", result)
: DEFAULT_MAC_ITERATION_COUNT;
}
private static int string2IC(String type, String value) {

View file

@ -1144,33 +1144,33 @@ jceks.key.serialFilter = java.base/java.lang.Enum;java.base/java.security.KeyRep
# The algorithm used to encrypt a certificate. This can be any non-Hmac PBE
# algorithm defined in the Cipher section of the Java Security Standard
# Algorithm Names Specification. When set to "NONE", the certificate
# is not encrypted. The default value is "PBEWithSHA1AndRC2_40".
#keystore.pkcs12.certProtectionAlgorithm = PBEWithSHA1AndRC2_40
# is not encrypted. The default value is "PBEWithHmacSHA256AndAES_256".
#keystore.pkcs12.certProtectionAlgorithm = PBEWithHmacSHA256AndAES_256
# The iteration count used by the PBE algorithm when encrypting a certificate.
# This value must be a positive integer. The default value is 50000.
#keystore.pkcs12.certPbeIterationCount = 50000
# This value must be a positive integer. The default value is 10000.
#keystore.pkcs12.certPbeIterationCount = 10000
# The algorithm used to encrypt a private key or secret key. This can be
# any non-Hmac PBE algorithm defined in the Cipher section of the Java
# Security Standard Algorithm Names Specification. The value must not be "NONE".
# The default value is "PBEWithSHA1AndDESede".
#keystore.pkcs12.keyProtectionAlgorithm = PBEWithSHA1AndDESede
# The default value is "PBEWithHmacSHA256AndAES_256".
#keystore.pkcs12.keyProtectionAlgorithm = PBEWithHmacSHA256AndAES_256
# The iteration count used by the PBE algorithm when encrypting a private key
# or a secret key. This value must be a positive integer. The default value
# is 50000.
#keystore.pkcs12.keyPbeIterationCount = 50000
# is 10000.
#keystore.pkcs12.keyPbeIterationCount = 10000
# The algorithm used to calculate the optional MacData at the end of a PKCS12
# file. This can be any HmacPBE algorithm defined in the Mac section of the
# Java Security Standard Algorithm Names Specification. When set to "NONE",
# no Mac is generated. The default value is "HmacPBESHA1".
#keystore.pkcs12.macAlgorithm = HmacPBESHA1
# no Mac is generated. The default value is "HmacPBESHA256".
#keystore.pkcs12.macAlgorithm = HmacPBESHA256
# The iteration count used by the MacData algorithm. This value must be a
# positive integer. The default value is 100000.
#keystore.pkcs12.macIterationCount = 100000
# positive integer. The default value is 10000.
#keystore.pkcs12.macIterationCount = 10000
#
# Enhanced exception message information
@ -1308,4 +1308,4 @@ jdk.io.permissionsUseCanonicalPath=false
# properties. In the case that both properties are simultaneously set, the
# System value prevails. The default value of the property is "false".
#
#jdk.security.allowNonCaAnchor=true
#jdk.security.allowNonCaAnchor=true