web-dev-qa-db-ja.com

Kerberos-AP REPを復号化するための適切なタイプのキーが見つからない-HMACを使用したRC4

Java WebAppにKerberos/SpNegoを使用してSSOを設定しようとしています。次を使用しています:

  • Java 1.7u67
  • org.springframework.security.kerberos 1.0.0.RELEASE
  • Active Directory
  • Linux上のTomcat 7

Tomcat/linuxサーバーでkerberosを構成する方法? で説明されている問題を解決した後、次のエラーが発生します。

org.springframework.security.authentication.BadCredentialsException: Kerberos validation not succesful
        at org.springframework.security.kerberos.authentication.Sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.Java:70) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        at org.springframework.security.kerberos.authentication.KerberosServiceAuthenticationProvider.authenticate(KerberosServiceAuthenticationProvider.Java:64) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.Java:156) ~[spring-security-core-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.kerberos.web.authentication.SpnegoAuthenticationProcessingFilter.doFilter(SpnegoAuthenticationProcessingFilter.Java:145) ~[spring-security-kerberos-web-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.Java:199) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.Java:110) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.Java:50) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.Java:87) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.Java:342) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.Java:192) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.Java:160) [spring-security-web-3.2.7.RELEASE.jar:3.2.7.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.Java:344) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.Java:261) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:241) [catalina.jar:7.0.55]
        at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:208) [catalina.jar:7.0.55]
        at org.lightadmin.core.view.TilesContainerEnrichmentFilter.doFilterInternal(TilesContainerEnrichmentFilter.Java:40) [lightadmin-1.2.0.RC1.jar:1.2.0.RC1]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:241) [catalina.jar:7.0.55]
        at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:208) [catalina.jar:7.0.55]
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.Java:77) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.Java:107) [spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
        at org.Apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.Java:241) [catalina.jar:7.0.55]
        at org.Apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.Java:208) [catalina.jar:7.0.55]
        at org.Apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.Java:220) [catalina.jar:7.0.55]
        at org.Apache.catalina.core.StandardContextValve.invoke(StandardContextValve.Java:122) [catalina.jar:7.0.55]
        at org.Apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.Java:501) [catalina.jar:7.0.55]
        at org.Apache.catalina.core.StandardHostValve.invoke(StandardHostValve.Java:171) [catalina.jar:7.0.55]
        at org.Apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.Java:103) [catalina.jar:7.0.55]
        at org.Apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.Java:950) [catalina.jar:7.0.55]
        at org.Apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.Java:116) [catalina.jar:7.0.55]
        at org.Apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.Java:408) [catalina.jar:7.0.55]
        at org.Apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.Java:1070) [Tomcat-coyote.jar:7.0.55]
        at org.Apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.Java:611) [Tomcat-coyote.jar:7.0.55]
        at org.Apache.Tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.Java:316) [Tomcat-coyote.jar:7.0.55]
        at Java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.Java:1145) [na:1.7.0_67]
        at Java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.Java:615) [na:1.7.0_67]
        at org.Apache.Tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.Java:61) [Tomcat-coyote.jar:7.0.55]
        at Java.lang.Thread.run(Thread.Java:745) [na:1.7.0_67]
Caused by: Java.security.PrivilegedActionException: null
        at Java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_67]
        at javax.security.auth.Subject.doAs(Subject.Java:415) ~[na:1.7.0_67]
        at org.springframework.security.kerberos.authentication.Sun.SunJaasKerberosTicketValidator.validateTicket(SunJaasKerberosTicketValidator.Java:67) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        ... 42 common frames omitted
Caused by: org.ietf.jgss.GSSException: Failure unspecified at GSS-API level (Mechanism level: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - RC4 with HMAC)
        at Sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.Java:788) ~[na:1.7.0_67]
        at Sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.Java:342) ~[na:1.7.0_67]
        at Sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.Java:285) ~[na:1.7.0_67]
        at Sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(SpNegoContext.Java:875) ~[na:1.7.0_67]
        at Sun.security.jgss.spnego.SpNegoContext.acceptSecContext(SpNegoContext.Java:548) ~[na:1.7.0_67]
        at Sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.Java:342) ~[na:1.7.0_67]
        at Sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.Java:285) ~[na:1.7.0_67]
        at org.springframework.security.kerberos.authentication.Sun.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.Java:162) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        at org.springframework.security.kerberos.authentication.Sun.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.Java:152) ~[spring-security-kerberos-core-1.0.0.RELEASE.jar:1.0.0.RELEASE]
        ... 45 common frames omitted
Caused by: Sun.security.krb5.KrbException: Invalid argument (400) - Cannot find key of appropriate type to decrypt AP REP - RC4 with HMAC
        at Sun.security.krb5.KrbApReq.authenticate(KrbApReq.Java:273) ~[na:1.7.0_67]
        at Sun.security.krb5.KrbApReq.<init>(KrbApReq.Java:144) ~[na:1.7.0_67]
        at Sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.Java:108) ~[na:1.7.0_67]
        at Sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.Java:771) ~[na:1.7.0_67]
        ... 53 common frames omitted

ただし、アプリケーションの起動時に次のデバッグを取得したため、キーはそこにあるはずです。

  Debug is  true storeKey true useTicketCache false useKeyTab true doNotPrompt true ticketCache is null isInitiator false KeyTab is /opt/pksvc/Tomcat_edl/current/conf/TestSpnego.keytab refreshKrb5Config is false principal is [email protected] tryFirstPass is false useFirstPass is false storePass is false clearPass is false
principal is [email protected]
Will use keytab
>>> KeyTabInputStream, readName(): MYREALM.DE
>>> KeyTabInputStream, readName(): HTTP
>>> KeyTabInputStream, readName(): lxdetstpksvc01.mydomain.de
>>> KeyTab: load() entry length: 83; type: 23
Ordering keys wrt default_tkt_enctypes list
Java config name: /opt/pksvc/Tomcat_edl/current/conf/krb5.conf
Loaded from Java config
default etypes for default_tkt_enctypes: 23.
Commit Succeeded

したがって、enctype 23 = RC4 with HMACはKeyTabエントリのタイプであり、デフォルトのenctypeです。また、ブラウザーがこのenctypeのトークンを送信していることもわかります(以下からバイナリ部分を削除しました)。

Ticket  TicketType{TktVno=5,Realm=MYREALM.DE,Sname=HTTP/lxdetstpksvc01.mydomain.de,EncPart=EncryptedData{Etype=23,Kvno=4,Cipher=binary[...  352 16728   KerberosV5.TicketType   
Authenticator   EncryptedData{Etype=23,Kvno=nothing,Cipher=binary[...   17080   2872    KerberosV5.EncryptedData    

そのため、すべてがencytpe 23(RC4 with HMAC)のようです。コードを確認したところ、KrbApReq(上記のスタックでエラーをスロー)が使用するSun.security.krb5.EncryptionKeyが実際にenctypeだけでなくバージョンも比較していることがわかりました。私の場合、それが間違っているに違いないと思います。上記のチケットでは、EncryptedDataの場合はKvno = 4で、Authenticator EncryptedDataの場合はKvno = nothingです。これらは一致する必要がありますか?

どうすればこれを解決できますか?これはキータブの生成に影響されますか?

14
Gunnar Kiesel

上記のエラーは2つの問題が原因であることが判明しました。

  1. Spring構成のサービスプリンシパルが間違っていました。 [email protected]でしたが、HTTP/[email protected]が正しいです。

  2. キータブのKvnoは、Active Directoryに保存されているKvnoと同じではありませんでした。 https://Tomcat.Apache.org/Tomcat-7.0-doc/windows-auth-howto.html に記載されているように、Active Directoryはktpassを実行するたびにKvnoを発生させます。ただし、ADでその値(msDS-KeyVersionNumber)を見つけることができず、リクエストからしか取得できませんでした。

「復号化する適切なタイプのキーが見つかりません...」エラーを要約すると、次の問題のいずれかが原因で発生する可能性があります。

  1. 春のセキュリティ構成のサービスprinicpalは、キータブからのサービス(ktpassのparam/princ)と同じではありません。
  2. ADがチケットを送信したenctypeのキーはありません(ktpassのparam/cryptoとkrb5.conf/permitted_enctypes + default_tkt_enctypesで設定)。
  3. チケットのKvnoは、キータブのKvnoとは異なります(ktpassのparam/kvno)。
  4. キータブへのパスが間違っている(Xavier Porteboisからの回答を参照)
  5. プロセスにはキータブを読み取る権限がありません( ser761 からのコメントを参照)
19
Gunnar Kiesel

Invalid argument (400) - Cannot find key of appropriate type to decrypt ...エラーも発生しました。

キータブへのパスが間違っているの場合、これは単純にスローできます(この場合、Dockerボリュームマッピングがそこにあるのを忘れていました)。

したがって、この奇妙な例外が発生する可能性があるため、keytabパスが正しいパスであることを確認してください。

8

私の場合、サーバーのjaas構成ファイルでは、パラメーター「storeKey」をtrueに設定する必要がありました。

0
hunger

春のセキュリティ構成のサービスprinicpalは、keytabのサービス(ktpassのparam/princ)とは異なります。

私の場合は同じでしたが、param/princが正しくありませんでした。 HTTPおよびドメイン部分は大文字でなければなりません。

正しい例:

HTTP/[email protected]

間違った例:

http/[email protected]

0
filip5114

これは、KDCとしてActive Directoryを使用していて、keytabユーザーがkeytabが使用している暗号化設定とは異なる暗号化設定に構成されている場合にもスローされます。私の場合、AES 128が構成されていて、AES 256が必要でした。AD内で構成を変更するだけで問題が解決しました。

0
KWoodie

私はこれに4時間苦労してきました

jaasファイルでパラメーター「storeKey」をtrueに設定すると、問題が解決しました

0
sdraxxi