diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java index 5d670e58810..050540b4cbc 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/crypto/key/KeyProvider.java @@ -42,6 +42,8 @@ import org.apache.hadoop.fs.CommonConfigurationKeysPublic; import javax.crypto.KeyGenerator; +import static org.apache.hadoop.fs.CommonConfigurationKeysPublic.HADOOP_SECURITY_CRYPTO_JCEKS_KEY_SERIALFILTER; + /** * A provider of secret key material for Hadoop applications. Provides an * abstraction to separate key storage from users of encryption. It @@ -61,6 +63,14 @@ public abstract class KeyProvider { CommonConfigurationKeysPublic.HADOOP_SECURITY_KEY_DEFAULT_BITLENGTH_KEY; public static final int DEFAULT_BITLENGTH = CommonConfigurationKeysPublic. HADOOP_SECURITY_KEY_DEFAULT_BITLENGTH_DEFAULT; + public static final String JCEKS_KEY_SERIALFILTER_DEFAULT = + "java.lang.Enum;" + + "java.security.KeyRep;" + + "java.security.KeyRep$Type;" + + "javax.crypto.spec.SecretKeySpec;" + + "org.apache.hadoop.crypto.key.JavaKeyStoreProvider$KeyMetadata;" + + "!*"; + public static final String JCEKS_KEY_SERIAL_FILTER = "jceks.key.serialFilter"; private final Configuration conf; @@ -394,6 +404,14 @@ public abstract class KeyProvider { */ public KeyProvider(Configuration conf) { this.conf = new Configuration(conf); + // Added for HADOOP-15473. Configured serialFilter property fixes + // java.security.UnrecoverableKeyException in JDK 8u171. + if(System.getProperty(JCEKS_KEY_SERIAL_FILTER) == null) { + String serialFilter = + conf.get(HADOOP_SECURITY_CRYPTO_JCEKS_KEY_SERIALFILTER, + JCEKS_KEY_SERIALFILTER_DEFAULT); + System.setProperty(JCEKS_KEY_SERIAL_FILTER, serialFilter); + } } /** diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java index 8837cfbd07c..9e0ba20c280 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/CommonConfigurationKeysPublic.java @@ -662,6 +662,13 @@ public class CommonConfigurationKeysPublic { * * core-default.xml */ + public static final String HADOOP_SECURITY_CRYPTO_JCEKS_KEY_SERIALFILTER = + "hadoop.security.crypto.jceks.key.serialfilter"; + /** + * @see + * + * core-default.xml + */ public static final String HADOOP_SECURITY_CRYPTO_BUFFER_SIZE_KEY = "hadoop.security.crypto.buffer.size"; /** Defalt value for HADOOP_SECURITY_CRYPTO_BUFFER_SIZE_KEY */ diff --git a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml index fad298587eb..95645879a75 100644 --- a/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml +++ b/hadoop-common-project/hadoop-common/src/main/resources/core-default.xml @@ -2486,6 +2486,29 @@ + + hadoop.security.crypto.jceks.key.serialfilter + + Enhanced KeyStore Mechanisms in JDK 8u171 introduced jceks.key.serialFilter. + If jceks.key.serialFilter is configured, the JCEKS KeyStore uses it during + the deserialization of the encrypted Key object stored inside a + SecretKeyEntry. + If jceks.key.serialFilter is not configured it will cause an error when + recovering keystore file in KeyProviderFactory when recovering key from + keystore file using JDK 8u171 or newer. The filter pattern uses the same + format as jdk.serialFilter. + + The value of this property will be used as the following: + 1. The value of jceks.key.serialFilter system property takes precedence + over the value of this property. + 2. In the absence of jceks.key.serialFilter system property the value of + this property will be set as the value of jceks.key.serialFilter. + 3. If the value of this property and jceks.key.serialFilter system + property has not been set, org.apache.hadoop.crypto.key.KeyProvider + sets a default value for jceks.key.serialFilter. + + + hadoop.security.crypto.buffer.size 8192