Estamos teniendo problemas de Kerberos/autenticación AD a trabajar con un Resorte de webapp, y creo que el problema tiene que ver con los tipos de cifrado para los tickets de Kerberos y el dominio de Active Directory nivel funcional.

La configuración básica es:

Tengo un entorno donde el dominio de Active Directory el nivel funcional de Windows Server 2003 y todo funciona bien, con los clientes de autenticación como se espera si se ha iniciado sesión en el dominio. El uso de kerbtray para examinar las entradas en este entorno, puedo ver que todos ellos tienen tanto el ticket de tipo de cifrado y la clave de cifrado de tipo «RSADSI RC4-HMAC».

Tengo un nuevo dominio con el nivel funcional de Windows Server 2008, y aquí es donde la autenticación no se realiza trabajo. La aplicación de error devuelto al intentar validar el billete es:

Kerberos validation not successful...
Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Checksum failed)
at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at sun.security.jgss.spnego.SpNegoContext.GSS_acceptSecContext(Unknown Source)
at sun.security.jgss.spnego.SpNegoContext.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at sun.security.jgss.GSSContextImpl.acceptSecContext(Unknown Source)
at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:146)
at org.springframework.security.extensions.kerberos.SunJaasKerberosTicketValidator$KerberosValidateAction.run(SunJaasKerberosTicketValidator.java:136)
... 34 more
Caused by: KrbException: Checksum failed
at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(Unknown Source)
at sun.security.krb5.EncryptedData.decrypt(Unknown Source)
at sun.security.krb5.KrbApReq.authenticate(Unknown Source)
at sun.security.krb5.KrbApReq.<init>(Unknown Source)
at sun.security.jgss.krb5.InitSecContextToken.<init>(Unknown Source)
... 43 more
Caused by: java.security.GeneralSecurityException: Checksum failed
at sun.security.krb5.internal.crypto.dk.ArcFourCrypto.decrypt(Unknown Source)
at sun.security.krb5.internal.crypto.ArcFourHmac.decrypt(Unknown Source)

La traza de la pila muestra «ArcfourCrypto.descifrar» así que, presumiblemente, es el tratamiento de los ticket de Kerberos como RC4-HMAC. El uso de kerbtray de nuevo para examinar las entradas de este momento hay 2 entradas en el cliente para el dominio: krbtgt/.COM. Tanto de los pasajes clave de cifrado tipo RSADS1 RC4-HMAC, también se tiene presente para su billete de tipo de cifrado, pero el otro tiene «Kerberos AES256-CTS-HMAC-SHA1-96».

No sé por seguro de que esta es la causa del problema, pero es la única diferencia que he sido capaz de encontrar en los dos entornos que podrían explicar la autenticación de excepción. He intentado cambiando el ANUNCIO de la política de cifrado, probé con IE y Firefox, y básicamente todo lo que podía pensar, pero nada ha funcionado.

Cualquier ayudar a hacer frente a esto sería muy apreciada. Prefiero solucionarlo en java final como yo, probablemente, no puede dictar demasiado acerca de la producción de ANUNCIOS de la instalación.

¿Has comprobado la comunicación en Wireshark y tengo los tickets examinado?
Gracias @Miguel-O – hice uso de Wireshark cuando se trabaja sobre esto antes, pero no tienen la salida está más disponible.Yo no era capaz de conseguir que esto funcione en absoluto – le volvió de la prueba de dominio de Windows Server 2003 nivel funcional y luego se trabajó normalmente. Ahora necesito la configuración de un nuevo 2008 dominio de prueba para intentar encontrar una solución viable….

OriginalEl autor slt | 2011-12-14

2 Comentarios

  1. 17

    El problema parece estar en el keytab. Hay algunas secuencias de acción que lleva a algunos específicos archivo keytab estados:
    (A) keytab funciona con Java, pero no funciona con k5start/kinit;
    (B) la clave no funciona con Java, pero funciona con k5start/kinit;
    (C) keytab trabaja con ellos.

    El corto código Java que permite comprobar si Java puede autenticar usando el archivo keytab:

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.InputStream;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Properties;
    import javax.security.auth.Subject;
    import com.sun.security.auth.module.Krb5LoginModule;
    /**
    * This is simple Java program that tests ability to authenticate 
    * with Kerberos using the JDK implementation.
    * 
    * The program uses no libraries but JDK itself.
    */
    public class Krb {
    private void loginImpl(final String propertiesFileName) throws Exception {
    System.out.println("NB: system property to specify the krb5 config: [java.security.krb5.conf]");
    //System.setProperty("java.security.krb5.conf", "/etc/krb5.conf");
    System.out.println(System.getProperty("java.version"));
    System.setProperty("sun.security.krb5.debug", "true");
    final Subject subject = new Subject();
    final Krb5LoginModule krb5LoginModule = new Krb5LoginModule();
    final Map<String,String> optionMap = new HashMap<String,String>();
    if (propertiesFileName == null) {
    //optionMap.put("ticketCache", "/tmp/krb5cc_1000");
    optionMap.put("keyTab", "/etc/krb5.keytab");
    optionMap.put("principal", "foo"); //default realm
    optionMap.put("doNotPrompt", "true");
    optionMap.put("refreshKrb5Config", "true");
    optionMap.put("useTicketCache", "true");
    optionMap.put("renewTGT", "true");
    optionMap.put("useKeyTab", "true");
    optionMap.put("storeKey", "true");
    optionMap.put("isInitiator", "true");
    } else {
    File f = new File(propertiesFileName);
    System.out.println("======= loading property file ["+f.getAbsolutePath()+"]");
    Properties p = new Properties();
    InputStream is = new FileInputStream(f);
    try {
    p.load(is);
    } finally {
    is.close();
    }
    optionMap.putAll((Map)p);
    }
    optionMap.put("debug", "true"); //switch on debug of the Java implementation
    krb5LoginModule.initialize(subject, null, new HashMap<String,String>(), optionMap);
    boolean loginOk = krb5LoginModule.login();
    System.out.println("======= login:  " + loginOk);
    boolean commitOk = krb5LoginModule.commit();
    System.out.println("======= commit: " + commitOk);
    System.out.println("======= Subject: " + subject);
    }
    public static void main(String[] args) throws Exception {
    System.out.println("A property file with the login context can be specified as the 1st and the only paramater.");
    final Krb krb = new Krb();
    krb.loginImpl(args.length == 0 ? null : args[0]);
    }
    }

    y el archivo de propiedades de uso:

    #ticketCache=/tmp/krb5cc_1000
    keyTab=/etc/krb5.keytab
    principal=foo
    doNotPrompt=true
    refreshKrb5Config=true
    useTicketCache=true
    renewTGT=true
    useKeyTab=true
    storeKey=true
    isInitiator=true

    (Abajo suponemos que krb/kdc está instalado y configurado correctamente, la base de datos se crea con kdb5_util. El estado inicial de cada uno de los comandos de la secuencia es: el archivo keytab eliminado, token caché se elimina, el usuario «foo» se elimina de la base de datos.)


    La siguiente secuencia de acción conduce a la keytab del estado (A):

    $ echo -e "foo\nfoo" | kadmin.local -q "addprinc foo"
    $ echo -e "foo\nfoo" | kadmin.local -q "ktadd foo"
    $ java -cp . Krb ./krb5.properties 
    # Now java auth okay, but the following command fails:
    $ k5start foo
    Kerberos initialization for [email protected].COM
    Password for [email protected].COM: 
    k5start: error getting credentials: Decrypt integrity check failed
    $

    La siguiente secuencia de acción conduce a la keytab del estado (B):

    $ echo -e "foo\nfoo" | kadmin.local -q "addprinc foo"
    $ echo -e "foo\nfoo" | kadmin.local -q "ktadd foo"
    $ echo -e "foo\nfoo" | kadmin.local -q "cpw foo"
    $ java -cp . Krb ./krb5.properties 
    A property file with the login context can be specified as the 1st and the only paramater.
    NB: system property to specify the krb5 config: [java.security.krb5.conf]
    1.6.0_33
    ======= loading property file [/tmp/krb-test/yhadoop-common/./krb5.properties]
    Debug is  true storeKey true useTicketCache true useKeyTab true doNotPrompt true ticketCache is null isInitiator true KeyTab is /etc/krb5.keytab refreshKrb5Config is true principal is foo tryFirstPass is false useFirstPass is false storePass is false clearPass is false
    Refreshing Kerberos configuration
    Config name: /etc/krb5.conf
    >>> KdcAccessibility: reset
    >>> KdcAccessibility: reset
    Acquire TGT from Cache
    >>>KinitOptions cache name is /tmp/krb5cc_0
    Principal is [email protected].COM
    null credentials from Ticket Cache
    >>> KeyTabInputStream, readName(): EXAMPLE.COM
    >>> KeyTabInputStream, readName(): foo
    >>> KeyTab: load() entry length: 49; type: 23
    Added key: 23version: 3
    Ordering keys wrt default_tkt_enctypes list
    default etypes for default_tkt_enctypes: 23.
    0: EncryptionKey: keyType=23 kvno=3 keyValue (hex dump)=
    0000: 5F 7F 9B 42 BB 02 51 81   32 05 1D 7B C0 9F 19 C0  _..B..Q.2.......
    principal's key obtained from the keytab
    Acquire TGT using AS Exchange
    default etypes for default_tkt_enctypes: 23.
    >>> KrbAsReq calling createMessage
    >>> KrbAsReq in createMessage
    >>> KrbKdcReq send: kdc=localhost UDP:88, timeout=30000, number of retries =3, #bytes=128
    >>> KDCCommunication: kdc=localhost UDP:88, timeout=30000,Attempt =1, #bytes=128
    >>> KrbKdcReq send: #bytes read=611
    >>> KrbKdcReq send: #bytes read=611
    >>> KdcAccessibility: remove localhost:88
    >>> EType: sun.security.krb5.internal.crypto.ArcFourHmacEType
    Checksum failed !
    [Krb5LoginModule] authentication failed 
    Checksum failed
    Exception in thread "main" javax.security.auth.login.LoginException: Checksum failed
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:696)
    at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:542)
    at Krb.loginImpl(Krb.java:65)
    at Krb.main(Krb.java:77)
    Caused by: KrbException: Checksum failed
    at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(ArcFourHmacEType.java:85)
    at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(ArcFourHmacEType.java:77)
    at sun.security.krb5.EncryptedData.decrypt(EncryptedData.java:168)
    at sun.security.krb5.KrbAsRep.<init>(KrbAsRep.java:87)
    at sun.security.krb5.KrbAsReq.getReply(KrbAsReq.java:446)
    at sun.security.krb5.Credentials.sendASRequest(Credentials.java:401)
    at sun.security.krb5.Credentials.acquireTGT(Credentials.java:350)
    at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:672)
    ... 3 more
    Caused by: java.security.GeneralSecurityException: Checksum failed
    at sun.security.krb5.internal.crypto.dk.ArcFourCrypto.decrypt(ArcFourCrypto.java:388)
    at sun.security.krb5.internal.crypto.ArcFourHmac.decrypt(ArcFourHmac.java:74)
    at sun.security.krb5.internal.crypto.ArcFourHmacEType.decrypt(ArcFourHmacEType.java:83)
    ... 10 more
    $

    Pero el «k5start foo» está bien en este estado, así como «kinit foo».


    Y la siguiente secuencia de acción conduce a un estado de (C):

    $ echo -e "foo\nfoo" | kadmin.local -q "addprinc foo"
    $ ktutil 
    ktutil:  addent -password -p foo -k 1 -e rc4-hmac
    Password for [email protected].COM: 
    ktutil:  wkt /etc/krb5.keytab
    ktutil:  q

    después de que ambos k5start/kinit y el java de verificación de dar resultado positivo.


    Medio ambiente:

    yum list krb5-appl-servers krb5-libs krb5-server krb5-workstation kstart pam_krb5 
    ...
    Installed Packages
    krb5-libs.x86_64                                                                            1.9-33.el6_3.3                                                                      @updates
    krb5-server.x86_64                                                                          1.9-33.el6_3.3                                                                      @updates
    krb5-workstation.x86_64                                                                     1.9-33.el6_3.3                                                                      @updates
    kstart.x86_64                                                                               4.1-2.el6                                                                           @epel   
    ...
    $ cat /etc/redhat-release 
    CentOS release 6.3 (Final)
    $ java -version
    java version "1.6.0_33"
    Java(TM) SE Runtime Environment (build 1.6.0_33-b03)
    Java HotSpot(TM) 64-Bit Server VM (build 20.8-b03, mixed mode)

    También el mismo comportamiento se observó con Java 7.
    También el mismo comportamiento se observó en Ubuntu precise (12.04.1 LTS) con MIT kerberos 5-1.10.3 compilado a partir de la distribución de código fuente.

    Bonita respuesta detallada!
    Soy capaz de recuperar el billete de keytab. Sin embargo, con Java 7 código, este falló de repente con la suma de comprobación de error de error. Es volver a crear la clave, la única opción?

    OriginalEl autor Ivan Veselovsky

  2. 0

    El problema es como los token se genera frente a la forma en que se valida en el lado del servidor. De la excepción de seguimiento, muestra el problema es, lado del cliente no es la suma de comprobación y el lado del servidor en la que se busca validar la suma de comprobación. La suma de comprobación es uno de los parámetros valor establecido en el símbolo que ha significado obvio.

    Debe haber una manera en 2008 para deshabilitar esta característica para ignorar la suma de comprobación de verificación. Pero se abre otra puerta y usted puede necesitar para evaluar el riesgo residual.

    OriginalEl autor tkar

Dejar respuesta

Please enter your comment!
Please enter your name here