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) {