jdk8u171开始增加了jceks.key.serialFilter属性限制证书序列化的类,增强安全性,不在这个属性中的类将会被拒绝Rejected, 从而导致kms服务重启后需要从keystore中反序列化加载SecretKeyEntry加密密钥时失败从而无法recover还原密钥信息。只要将被Rejected的类加入jre/lib/security/java.security中的jceks.key.serialFilter中就可以了。
jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;java.security.KeyRep$Type;javax.crypto.spec.SecretKeySpec;jceks.key.serialFiltercom.sun.crypto.provider.SealedObjectForKeyProtector;org.apache.hadoop.crypto.key.**;!*
KMS重启后无法查看key的metadata信息了,报错如下:
java.io.IOException: Can't recover key for testkey from keystore file:/home/hadoop/kms.jks
at org.apache.hadoop.crypto.key.JavaKeyStoreProvider.getmetadata(JavaKeyStoreProvider.java:422)
at org.apache.hadoop.crypto.key.CachingKeyProvider$CacheExtension$2.load(CachingKeyProvider.java:65)
at org.apache.hadoop.crypto.key.CachingKeyProvider$CacheExtension$2.load(CachingKeyProvider.java:62)
......Caused by: java.security.UnrecoverableKeyException: Rejected by the jceks.key.serialFilter or jdk.serialFilter property
at com.sun.crypto.provider.KeyProtector.unseal(KeyProtector.java:399)
at com.sun.crypto.provider.JceKeyStore.engineGetKey(JceKeyStore.java:144)
at java.security.KeyStore.getKey(KeyStore.java:1023)
at org.apache.hadoop.crypto.key.JavaKeyStoreProvider.getmetadata(JavaKeyStoreProvider.java:408)
... 61 more
先查看异常抛出位置的代码,异常是hadoop的JavaKeyStoreProvider以及java的jrelibextsunjce_provider.jar下的KeyProtector类。
报错在jdk的代码里应该和hadoop无关了,根据报错信息Rejected by the jceks.key.serialFilter or jdk.serialFilter property查找下这个jceks.key.serialFilter是什么。
Java™ SE Development Kit 8, Update 171 Release Notes
大意就是jdk8新特性,不在这个jceks.key.serialFilter允许的类型中的自定义类会被拒绝使用。那只要从kms异常日志中找到hadoop使用的类型加上去就可以了。
cd ${JAVA_HOME}/jre/lib/security
vi java.security
找到jceks.key.serialFilter的位置在!*前增加jceks.key.serialFiltercom.sun.crypto.provider.SealedObjectForKeyProtector;org.apache.hadoop.crypto.key.**;
修改为
jceks.key.serialFilter = java.lang.Enum;java.security.KeyRep;java.security.KeyRep$Type;com.sun.crypto.provider.SealedObjectForKeyProtector;javax.crypto.spec.SecretKeySpec;org.apache.hadoop.crypto.key.**;!*
分隔符是;
!*表示除了已配置的,其他所有类都拒绝
在hadoop的core-site.xml可以设置
不过,jdk的配置优先级高,以jdk的java.security中jceks.key.serialFilter配置为准。
Hadoop2.7.7 API: core-site.xml 解析_张伯毅的博客-CSDN博客
Java™ SE Development Kit 8, Update 171 Release Notes



