8267319: Use larger default key sizes and algorithms based on CNSA

Reviewed-by: weijun, xuelei
This commit is contained in:
Valerie Peng 2022-03-24 22:50:26 +00:00
parent c1048021fe
commit 313bc7f64f
29 changed files with 496 additions and 178 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -34,7 +34,7 @@ import java.util.Arrays;
import javax.crypto.KeyGeneratorSpi;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import sun.security.util.SecurityProviderConstants;
/**
* This class generates a AES key.
@ -46,7 +46,8 @@ import javax.crypto.spec.SecretKeySpec;
public final class AESKeyGenerator extends KeyGeneratorSpi {
private SecureRandom random = null;
private int keySize = 16; // default keysize (in number of bytes)
// default keysize (in number of bytes)
private int keySize = SecurityProviderConstants.getDefAESKeySize() >> 3;
/**
* Empty constructor.

View file

@ -1917,6 +1917,8 @@ public final class Main {
keysize = SecurityProviderConstants.DEF_EC_KEY_SIZE;
} else if ("RSA".equalsIgnoreCase(keyAlgName)) {
keysize = SecurityProviderConstants.DEF_RSA_KEY_SIZE;
} else if ("RSASSA-PSS".equalsIgnoreCase(keyAlgName)) {
keysize = SecurityProviderConstants.DEF_RSASSA_PSS_KEY_SIZE;
} else if ("DSA".equalsIgnoreCase(keyAlgName)) {
keysize = SecurityProviderConstants.DEF_DSA_KEY_SIZE;
} else if ("EdDSA".equalsIgnoreCase(keyAlgName)) {

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -27,9 +27,12 @@ package sun.security.util;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.PatternSyntaxException;
import java.security.InvalidParameterException;
import java.security.ProviderException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import sun.security.action.GetPropertyAction;
/**
@ -43,11 +46,11 @@ public final class SecurityProviderConstants {
private static final Debug debug =
Debug.getInstance("jca", "ProviderConfig");
// cache for provider aliases; key is the standard algorithm name
// Cache for provider aliases; key is the standard algorithm name
// value is the associated aliases List
private static final ConcurrentHashMap<String, List<String>> aliasesMap;
// utility method for generating aliases list using the supplied
// Utility method for generating aliases list using the supplied
// 'oid' and 'extraAliases', then store into "aliasesMap" cache under the
// key 'stdName'
private static List<String> store(String stdName, KnownOIDs oid,
@ -75,7 +78,7 @@ public final class SecurityProviderConstants {
return value;
}
// returns an aliases List for the specified algorithm name o
// Return an aliases List for the specified algorithm name o
// NOTE: exception is thrown if no aliases nor oid found, so
// only call this method if aliases are expected
public static List<String> getAliases(String o) {
@ -105,6 +108,25 @@ public final class SecurityProviderConstants {
}
}
public static final int getDefAESKeySize() {
int currVal = DEF_AES_KEY_SIZE.get();
if (currVal == -1) {
int v = 256; // default AES key size
try {
// adjust if crypto policy only allows a smaller value
int max = Cipher.getMaxAllowedKeyLength("AES");
if (v > max) {
v = max;
}
} catch (NoSuchAlgorithmException ne) {
// should never happen; ignore and use the default
}
DEF_AES_KEY_SIZE.compareAndSet(-1, v);
currVal = v;
}
return currVal;
}
public static final int DEF_DSA_KEY_SIZE;
public static final int DEF_RSA_KEY_SIZE;
public static final int DEF_RSASSA_PSS_KEY_SIZE;
@ -112,6 +134,11 @@ public final class SecurityProviderConstants {
public static final int DEF_EC_KEY_SIZE;
public static final int DEF_ED_KEY_SIZE;
public static final int DEF_XEC_KEY_SIZE;
// The logic for finding the max allowable value in getDefAESKeySize()
// interferes with provider loading logic and may lead to deadlocks if
// called inside a static block. So, it is deferred to a later time when
// DEF_AES_KEY_SIZE is actually used/needed.
private static final AtomicInteger DEF_AES_KEY_SIZE;
private static final String KEY_LENGTH_PROP =
"jdk.security.defaultKeySize";
@ -120,12 +147,13 @@ public final class SecurityProviderConstants {
String keyLengthStr = GetPropertyAction.privilegedGetProperty
(KEY_LENGTH_PROP);
int dsaKeySize = 2048;
int rsaKeySize = 2048;
int rsaKeySize = 3072;
int rsaSsaPssKeySize = rsaKeySize; // default to same value as RSA
int dhKeySize = 2048;
int ecKeySize = 256;
int dhKeySize = 3072;
int ecKeySize = 384;
int edKeySize = 255;
int xecKeySize = 255;
int aesKeySize = -1; // needs to check crypto policy
if (keyLengthStr != null) {
try {
@ -167,6 +195,8 @@ public final class SecurityProviderConstants {
edKeySize = value;
} else if (algoName.equals("XDH")) {
xecKeySize = value;
} else if (algoName.equals("AES")) {
aesKeySize = value;
} else {
if (debug != null) {
debug.println("Ignoring unsupported algo in " +
@ -195,6 +225,7 @@ public final class SecurityProviderConstants {
DEF_EC_KEY_SIZE = ecKeySize;
DEF_ED_KEY_SIZE = edKeySize;
DEF_XEC_KEY_SIZE = xecKeySize;
DEF_AES_KEY_SIZE = new AtomicInteger(aesKeySize);
// Set up aliases with default mappings
// This is needed when the mapping contains non-oid

View file

@ -60,13 +60,11 @@ public class SignatureUtil {
if (algName.startsWith("OID.")) {
algName = algName.substring(4);
}
KnownOIDs ko = KnownOIDs.findMatch(algName);
if (ko != null) {
return ko.stdName().toUpperCase(Locale.ENGLISH);
}
}
return algName;
}
@ -491,12 +489,11 @@ public class SignatureUtil {
* @return the default alg, might be null if unsupported
*/
public static String getDefaultSigAlgForKey(PrivateKey k) {
String kAlg = k.getAlgorithm();
return switch (kAlg.toUpperCase(Locale.ENGLISH)) {
case "DSA", "RSA" -> ifcFfcStrength(KeyUtil.getKeySize(k))
+ "with" + kAlg;
case "EC" -> ecStrength(KeyUtil.getKeySize(k))
+ "withECDSA";
String kAlg = k.getAlgorithm().toUpperCase(Locale.ENGLISH);
return switch (kAlg) {
case "DSA" -> "SHA256withDSA";
case "RSA" -> ifcFfcStrength(KeyUtil.getKeySize(k)) + "withRSA";
case "EC" -> ecStrength(KeyUtil.getKeySize(k)) + "withECDSA";
case "EDDSA" -> k instanceof EdECPrivateKey
? ((EdECPrivateKey) k).getParams().getName()
: kAlg;
@ -521,11 +518,16 @@ public class SignatureUtil {
64, PSSParameterSpec.TRAILER_FIELD_BC);
}
// The following values are from SP800-57 part 1 rev 4 tables 2 and 3
// SP800-57 part 1 rev5 table 2 "Comparable security strengths of
// symmetric block cipher and asymmetric-key algorithms", and table 3
// "Maximum security strengths for hash and hash-based functions"
// define security strength for various algorithms.
// Besides matching the security strength, the default algorithms may
// also be chosen based on various recommendations such as NIST CNSA.
/**
* Return the default message digest algorithm with the same security
* strength as the specified EC key size.
* Return the default message digest algorithm based on the specified
* EC key size.
*
* Attention: sync with the @implNote inside
* {@link jdk.security.jarsigner.JarSigner.Builder#getDefaultSignatureAlgorithm}.
@ -533,27 +535,27 @@ public class SignatureUtil {
private static String ecStrength (int bitLength) {
if (bitLength >= 512) { // 256 bits of strength
return "SHA512";
} else if (bitLength >= 384) { // 192 bits of strength
} else {
// per CNSA, use SHA-384
return "SHA384";
} else { // 128 bits of strength and less
return "SHA256";
}
}
/**
* Return the default message digest algorithm with the same security
* strength as the specified IFC/FFC key size.
* Return the default message digest algorithm based on both the
* security strength of the specified IFC/FFC key size, i.e. RSA,
* RSASSA-PSS, and the recommendation from NIST CNSA, e.g. use SHA-384
* and min 3072-bit.
*
* Attention: sync with the @implNote inside
* {@link jdk.security.jarsigner.JarSigner.Builder#getDefaultSignatureAlgorithm}.
*/
private static String ifcFfcStrength (int bitLength) {
if (bitLength > 7680) { // 256 bits
private static String ifcFfcStrength(int bitLength) {
if (bitLength > 7680) { // 256 bits security strength
return "SHA512";
} else if (bitLength > 3072) { // 192 bits
return "SHA384";
} else { // 128 bits and less
return "SHA256";
} else {
// per CNSA, use SHA-384 unless keysize is too small
return (bitLength >= 624 ? "SHA384" : "SHA256");
}
}
}