加载秘钥java.security.InvalidKeyException: IOException : Short read of DER length异常处理
用如下方法加载私钥时,可能会抛出java.security.InvalidKeyException: IOException : Short read of DER length:
public static PrivateKey getPrivateKeyFromBytes(String crtBase64, String type) throws Exception { try { byte[] baKey = Base64.decode(crtBase64); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey prvkey = keyFactory.generatePrivate( type.equals("PKCS") ? new PKCS8EncodedKeySpec(baKey) : new X509EncodedKeySpec(baKey)); return prvkey; } catch (Exception e) { throw new Exception("读取私钥失败" + e.getMessage()); } }
异常详情类似如下:
Caused by: java.security.InvalidKeyException: IOException : Short read of DER length at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:351) at sun.security.pkcs.PKCS8Key.decode(PKCS8Key.java:356) at sun.security.rsa.RSAPrivateCrtKeyImpl.<init>(RSAPrivateCrtKeyImpl.java:91) at sun.security.rsa.RSAPrivateCrtKeyImpl.newKey(RSAPrivateCrtKeyImpl.java:75) at sun.security.rsa.RSAKeyFactory.generatePrivate(RSAKeyFactory.java:316) at sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:213) at com.alipay.api.internal.util.AlipaySignature.rsa256Sign(AlipaySignature.java:141) at com.alipay.api.internal.util.AlipaySignature.rsaSign(AlipaySignature.java:102) at com.alipay.api.DefaultAlipayClient.getRequestHolderWithSign(DefaultAlipayClient.java:323) at com.alipay.api.DefaultAlipayClient.doPost(DefaultAlipayClient.java:452) at com.alipay.api.DefaultAlipayClient._execute(DefaultAlipayClient.java:403) at com.alipay.api.DefaultAlipayClient.execute(DefaultAlipayClient.java:130) at com.alipay.api.DefaultAlipayClient.execute(DefaultAlipayClient.java:117) at com.alipay.api.DefaultAlipayClient.execute(DefaultAlipayClient.java:111) at sun.reflect.GeneratedMethodAccessor164.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
导致异常的原因通常有两种:第一,JDK加密算法问题,第二,秘钥内容自身问题。
JDK jar包问题
因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制。比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件。
下载与JDK或JRE对应版本的jce文件包,如jdk为1.8,所以下载 jce_policy-8.zip,官网下载地址:https://www.oracle.com/java/technologies/javase-jce8-downloads.html
下载解压后,把jar文件上传到需要安装jce机器上JDK或JRE的security目录下,覆盖源文件即可。
JDK:将两个jar文件放到%JDK_HOME%\jre\lib\security下
JRE:将两个jar文件放到%JRE_HOME%\lib\security下
覆盖之前,记得备份源文件,以防万一。
秘钥问题
秘钥自身问题就比较多,比如秘钥是否处理注释部分。或者秘钥存储是否完整等等。
个人遇到的一种情况是:秘钥存储在数据库中,数据库的字段长度设置的过短,导致秘钥在存储时被截取了,抛出上述异常。
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接
本文链接:https://choupangxia.com/2022/01/25/java-security-invalidkeyexception/