1

I am trying to integrate Okta into a spring application that already has spring security implemented. I have successfully added spring saml into the project an am able to successfully log into the app. However it is using the default java key store and I would like to use another jks as suggested in the documentation(http://docs.spring.io/spring-security-saml/docs/current/reference/html/security.html).

I have a couple of questions regarding the way spring saml extension works in regards to the jks.

  1. The sample jks contains two keys. One which is PrivateKeyEntry and one is trustedCertEntry. Is the "trustedCertEntry" the public key that is supposed to be gathered from the IDP?
  2. I believe that the JKS is used to decrypt assertion messages and not used for the https handshake. Is that assumption correct?

I am able to successfully do a login when using the provided JKS with apollo and startcom. However when I enable the assertion encryption(Encryption Algorithm: AES256-CBC, Key Transport Algorithm: RSA-OAEP) in my SAML config under Okta it starts to fail. I believe this is because I am not using the IDP's public key, so I obtained my Okta cert file.

I did the following to create a new jks and import the cert file:

keytool -genkeypair -alias self-signed -keypass default1! -keystore samlKeystore.jks

keytool -importcert -alias okta-pub -file okta.cert -keystore samlKeystore.jks

So now my keystore is as follows:

keytool -list -keystore samlKeystore.jks
Enter keystore password:
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

okta-pub, Jul 19, 2016, trustedCertEntry,
Certificate fingerprint (SHA1): F2:2C:97:68:47:AF:17:B3:B0:9D:C0:07:09:2F:9A:90:DF:79:E5:CD
self-signed, Jul 19, 2016, PrivateKeyEntry,
Certificate fingerprint (SHA1): 99:21:35:CA:AA:AF:33:44:81:78:67:95:7A:1D:1D:6A:BA:5C:96:5D

I update my security context file to:

    <bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
    <constructor-arg value="classpath:security/samlKeystore.jks"/>
    <constructor-arg type="java.lang.String" value="default1!"/>
    <constructor-arg>
        <map>
            <entry key="self-signed" value="default1!"/>
        </map>
    </constructor-arg>
    <constructor-arg type="java.lang.String" value="self-signed"/>
</bean>

When I try to do a SAML Login I am getting this exception:

[talledLocalContainer] 190716 12.43.03,777 {} {} {} ERROR (Decrypter.java:639) Failed to decrypt EncryptedKey, valid decryption key could not be resolved
[talledLocalContainer] 190716 12.43.03,777 {} {} {} ERROR (Decrypter.java:532) Failed to decrypt EncryptedData using either EncryptedData KeyInfoCredentialResolver or EncryptedKeyResolver + EncryptedKey KeyInfoCredentialResolver
[talledLocalContainer] 190716 12.43.03,778 {} {} {} ERROR (Decrypter.java:143) SAML Decrypter encountered an error decrypting element content
[talledLocalContainer] org.opensaml.xml.encryption.DecryptionException: Failed to decrypt EncryptedData

I have tried using the JCE unlimited strength library as mentioned here: Decrypting encrypted assertion using SAML 2.0 in java using OpenSAML. But that did not solve my problem.

Any suggestions? Am I creating my jks file correct?

EDIT 1: This is the full stack trace:

[talledLocalContainer] 190716 13.45.27,717 {} {} {} ERROR (Decrypter.java:143) SAML Decrypter encountered an error decrypting element content
[talledLocalContainer] org.opensaml.xml.encryption.DecryptionException: Failed to decrypt EncryptedData
[talledLocalContainer]  at org.opensaml.xml.encryption.Decrypter.decryptDataToDOM(Decrypter.java:535) ~[xmltooling-1.4.1.jar:?]
[talledLocalContainer]  at org.opensaml.xml.encryption.Decrypter.decryptDataToList(Decrypter.java:442) ~[xmltooling-1.4.1.jar:?]
[talledLocalContainer]  at org.opensaml.xml.encryption.Decrypter.decryptData(Decrypter.java:403) ~[xmltooling-1.4.1.jar:?]
[talledLocalContainer]  at org.opensaml.saml2.encryption.Decrypter.decryptData(Decrypter.java:141) [opensaml-2.6.1.jar:?]
[talledLocalContainer]  at org.opensaml.saml2.encryption.Decrypter.decrypt(Decrypter.java:69) [opensaml-2.6.1.jar:?]
[talledLocalContainer]  at org.springframework.security.saml.websso.WebSSOProfileConsumerImpl.processAuthenticationResponse(WebSSOProfileConsumerImpl.java:199) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
[talledLocalContainer]  at org.springframework.security.saml.SAMLAuthenticationProvider.authenticate(SAMLAuthenticationProvider.java:87) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
[talledLocalContainer]  at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156) [spring-security-core-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.saml.SAMLProcessingFilter.attemptAuthentication(SAMLProcessingFilter.java:87) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:166) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at com.aspectsecurity.contrast.teamserver.security.auth.rest.RestAuthenticationFilter.doFilter(RestAuthenticationFilter.java:67) [RestAuthenticationFilter.class:?]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:125) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.saml.metadata.MetadataGeneratorFilter.doFilter(MetadataGeneratorFilter.java:87) [spring-security-saml2-core-1.0.2.RELEASE.jar:1.0.2.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) [spring-security-web-3.2.9.RELEASE.jar:3.2.9.RELEASE]
[talledLocalContainer]  at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.1.8.RELEASE.jar:4.1.8.RELEASE]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at com.aspectsecurity.contrast.teamserver.webapp.filter.WebSecurityFilter.doFilter(WebSecurityFilter.java:79) [WebSecurityFilter.class:?]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at com.aspectsecurity.contrast.teamserver.webapp.filter.ESAPIThreadLocalFilter.doFilter(ESAPIThreadLocalFilter.java:34) [ESAPIThreadLocalFilter.class:?]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71) [log4j-web-2.4.1.jar:2.4.1]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423) [catalina.jar:7.0.61]
[talledLocalContainer]  at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079) [tomcat-coyote.jar:7.0.61]
[talledLocalContainer]  at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:620) [tomcat-coyote.jar:7.0.61]
[talledLocalContainer]  at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318) [tomcat-coyote.jar:7.0.61]
[talledLocalContainer]  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [?:1.7.0_79]
[talledLocalContainer]  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [?:1.7.0_79]
[talledLocalContainer]  at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-coyote.jar:7.0.61]
[talledLocalContainer]  at java.lang.Thread.run(Thread.java:745) [?:1.7.0_79]
Community
  • 1
  • 1
Dan
  • 1,041
  • 1
  • 12
  • 32

1 Answers1

2

The sample jks contains two keys. One which is PrivateKeyEntry and one is trustedCertEntry. Is the "trustedCertEntry" the public key that is supposed to be gathered from the IDP?

Yes, the public certificates from the IDPs you add to the keystore will show up as "trustedCertEntry".

I believe that the JKS is used to decrypt assertion messages and not used for the https handshake. Is that assumption correct?

This is correct. The JKS is not used for https in this case.

The way you have generated the keystore looks correct compared to what the documentation states. I recently generated my own keystore for using the following:

--generate keystore
keytool -genkeypair -alias mysaml -keypass password -keystore samlKeystore.jks -keyalg RSA -keysize 2048
--export cert for import into IDP
keytool -export -keystore samlKeystore.jks -alias myalias -file mysaml.cer
--add cert form IDP
keytool -importcert -alias myidp -file myidp.cer -keystore samlKeystore.jks

I recall using RSA due to some cryptographic error I was getting, but cannot recall if it was the same issue as yours.

I suggest double checking the installation of the JCE unlimited strength library. It's easy to not install it quite right, i.e. if you unzip it to the wrong location.

blur0224
  • 972
  • 8
  • 26
  • Thanks for the information! Regarding the keytool commands you provided; why are you exporting the keystore as a cert and then adding it again? I got a cert file from the IDP and did the import command with that. Did you just use the ```-keyalg RSA``` command for RSA? – Dan Jul 20 '16 at 13:22
  • 1
    The first command generates the keystore. The second command exports a public certificate that can be loaded into the IDP. The third is an example of how to load in an IDP cert. Yes, I used -keyalg RSA for to make it RSA. – blur0224 Jul 20 '16 at 13:30
  • My problem was I did not export the .cer file from the second keytool command you have listed. Thank you for the assistance! – Dan Jul 20 '16 at 14:37
  • Does this mean that as a SP we must provide the user with a public cert to upload to their IDP? The documentation that I've read shows that the IDP would provide a public cert for the SP. – Dan Jul 20 '16 at 14:43
  • 1
    If you end up using a CA signed certificate at some point (as per your requirements), and the CA root cert is loaded into the IDP already, adding the cert manually is no longer required. I have done this with an entrust certificate and ADFS as the IDP. If it is self signed, the only way for the signature verification to happen is if the cert is manually loaded into the IDP. – blur0224 Jul 20 '16 at 14:44
  • Question regarding the second keytool command ```keytool -export -keystore samlKeystore.jks -alias myalias -file mysaml.cer```. When the key store is created, there is only one PrivateKeyEntry. By doing this export are you exporting the private key or does it create a public key as the cer file? – Dan Jul 20 '16 at 15:38
  • 1
    You are not exporting the private key. That would be very bad. It's creating a public certificate, which you can verify by open the .cer file and looking at the details of the certificate. – blur0224 Jul 20 '16 at 15:45
  • checkout this library: https://github.com/ulisesbocchio/spring-boot-security-saml you can provide cert and key in PEM and DER format respectively without JKS – Ulises Jul 27 '16 at 07:22