mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8267319: Use larger default key sizes and algorithms based on CNSA
Reviewed-by: weijun, xuelei
This commit is contained in:
parent
c1048021fe
commit
313bc7f64f
29 changed files with 496 additions and 178 deletions
|
@ -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.
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue