别名为 mykey 的 SAML-Key 没有私钥
Posted
技术标签:
【中文标题】别名为 mykey 的 SAML-Key 没有私钥【英文标题】:SAML-Key with alias mykey doesn't have a private key 【发布时间】:2016-09-22 11:46:30 【问题描述】:我正在尝试使用 saml 修改 spring-boot 安全示例程序。 https://github.com/vdenotaris/spring-boot-security-saml-sample。我从身份提供商那里获得了证书(.crt),并尝试创建一个示例密钥库(.jks)来测试我的连接,然后再集成到我的应用程序中。 我按照以下步骤创建证书。
创建密钥库
keytool -keystore mykeystore.jks -genkey -alias saml
当我尝试列出我的密钥库时,我有一个私钥
列出密钥库
keytool -list -V -storepass changeit -keystore mykeystore.jks
我使用以下命令导入了 IDP 团队提供的证书。
keytool -import -file myidp.crt -storepass changeit -keystore mykeystore.jks
现在,当我列出我的 jks 文件时,我有两个条目,一个是私有的。
Keystore type: JKS
Keystore provider: SUN
Your keystore contains 2 entries
Alias name: saml
Creation date: May 24, 2016
Entry type: PrivateKeyEntry
XXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXX
*******************************************
*******************************************
Alias name: mykey
Creation date: May 24, 2016
Entry type: trustedCertEntry
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*******************************************
*******************************************
我修改了 WebSecurityConfi.java 类,在将 crt 导入密钥库时没有提供任何密码。我试图保持别名相同,但后来出现错误。
keytool error: java.lang.Exception: **Public keys in reply and keystore don't match
@Bean
public KeyManager keyManager()
DefaultResourceLoader loader = new DefaultResourceLoader();
Resource storeFile = loader.getResource("classpath:/saml/myKeystore.jks");
String storePass = "changeit";
Map<String, String> passwords = new HashMap<>();
passwords.put("changeit", "changeit");
String defaultKey = "mykey";
return new JKSKeyManager(storeFile, storePass, passwords, defaultKey);
现在我遇到了异常,我知道这是我的 JKS 创建的一些问题。您能否建议如何为我的受信任商店添加私钥。我只收到了来自 IDP 提供商的 .crt 文件。我是否必须执行任何其他步骤才能为我的受信任商店添加私钥?我检查了几个帖子,例如Key with alias xxx doesn't have a private key with Spring SAML,与我的问题类似,但我无法找出证书创建的问题。
错误 [http-nio-8080-exec-4] (DirectJDKLog.java:182) - Servlet [dispatcherServlet] 在路径 [] 的上下文中的 Servlet.service() 引发异常 java.lang.RuntimeException: 具有别名 mykey 的密钥没有私钥 在 org.springframework.security.saml.metadata.MetadataGenerator.getServerKeyInfo(MetadataGenerator.java:209) 在 org.springframework.security.saml.metadata.MetadataGenerator.buildSPSSODescriptor(MetadataGenerator.java:329) 在 org.springframework.security.saml.metadata.MetadataGenerator.generateMetadata(MetadataGenerator.java:189) 在 org.springframework.security.saml.metadata.MetadataGeneratorFilter.processMetadataInitialization(MetadataGeneratorFilter.java:127) 在 org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:86) 在 org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 在 org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213) 在 org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176) 在 org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346) 在 org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) 在 org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 在 org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 在 org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 在 org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212) 在 org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 在 org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 在 org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 在 org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 在 org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 在 org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:521) 在 org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1096) 在 org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) 在 org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 在 java.lang.Thread.run(Thread.java:745) 调试 [http-nio-8080-exec-4] (DispatcherServlet.java:861) - 名称为“dispatcherServlet”的 DispatcherServlet 处理 [/error] 的 GET 请求 调试 [http-nio-8080-exec-4] (AbstractHandlerMethodMapping.java:318) - 查找路径 /error 的处理程序方法 调试 [http-nio-8080-exec-4] (AbstractHandlerMethodMapping.java:325) - 返回处理程序方法 [public org.springframework.http.ResponseEntity> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet .http.HttpServletRequest)] 调试 [http-nio-8080-exec-4] (AbstractBeanFactory.java:251) - 返回单例 bean 'basicErrorController' 的缓存实例 调试 [http-nio-8080-exec-4] (DispatcherServlet.java:947) - [/error] 的 Last-Modified 值为:-1 调试 [http-nio-8080-exec-4] (AbstractMessageConverterMethodProcessor.java:225) - 编写 [timestamp=Tue May 24 19:12:00 IST 2016, status=500, error=Internal Server Error, exception=java. lang.RuntimeException, message=Key with alias mykey doesn't have a private key, path=/favicon.ico] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.映射Jackson2HttpMessageConverter@380682cd] 调试 [http-nio-8080-exec-4] (DispatcherServlet.java:1034) - 空 ModelAndView 返回到名为“dispatcherServlet”的 DispatcherServlet:假设 HandlerAdapter 完成了请求处理
【问题讨论】:
link between private key and signed certificate in keystore的可能重复 【参考方案1】:您需要使用与私钥相同的别名导入签名证书。
现在,当我列出我的 jks 文件时,我有两个条目,一个是私有的
你应该只有一个,私人的。
【讨论】:
我已经尝试过了,但后来我遇到了错误。 keytool 错误:java.lang.Exception:回复中的公钥和密钥库不匹配 那你有错误的 KeyStore 或者错误的别名或者错误的证书。你从一个有别名的密钥对开始;您从相同的别名生成了 CSR:您从 CSR 获得了签名证书;那么您需要将签名证书导入到具有相同别名的同一个 KeyStore 中。【参考方案2】:您的密钥库中可以有任意数量的私钥条目...但是您只能将一个私钥配置为 spring saml...您的私钥应该是 Entry type: PrivateKeyEntry
类型的...并更新您的 spring-security .xml 具有私钥的别名。例如。
<!-- Central storage of cryptographic keys -->
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:keycloak.jks"/>
<constructor-arg type="java.lang.String" value="password"/>
<constructor-arg>
<map>
<entry key="YOUR_ALIAS" value="password"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="YOUR_ALIAS"/>
</bean>
【讨论】:
以上是关于别名为 mykey 的 SAML-Key 没有私钥的主要内容,如果未能解决你的问题,请参考以下文章
如何将android位图别名为另一个尺寸的drawable(drawable-large-mdpi别名为drawable-hdpi)