Question

Au moment où je reçois une exception KrbException: la vérification de l'intégrité du champ déchiffré a échoué (31) avec mon application de démonstration GSS (côté serveur). Maintenant, je cherche la raison de cela. J'ai le soupçon, cela vient du fait que

  1. le client et l'application serveur s'exécutent sur le même ordinateur (localhost) et / ou
  2. le SPN a été généré pour une autre machine (ordinateur)

Le second signifie que le principal du service a été généré pour une machine xxx0815.domain.net. Le SPN est donc HTTP/xxx0815.domain.net@DOMAIN.NET. Et ma machine n’est pas celle-là, mais j’ai le fichier keytab pour que la méthode de connexion du serveur réussisse.

Est-ce que je soupçonne correctement ou est-ce que je fais une autre erreur?

Configuration du serveur et code source:
server.conf

Server { 
    com.sun.security.auth.module.Krb5LoginModule 
        required 
        isInitiator=false 
        doNotPrompt=true 
        useKeyTab=true 
        keyTab="gssdemo.keytab" 
        storeKey=true 
        principal="HTTP/xxx0815.domain.net@DOMAIN.NET" 
        debug=true; 
};

GSSServer.java (omis du contenu passe-partout)

    GSSManager manager = GSSManager.getInstance();
    GSSName serverName = manager.createName(getServerName(), null);
    GSSCredential serverCred = manager.createCredential(serverName,
                                                        GSSCredential.INDEFINITE_LIFETIME,
                                                        createKerberosOid(),
                                                        GSSCredential.ACCEPT_ONLY);
    GSSContext context = manager.createContext(serverCred);
    System.out.println("Context created successfully. Now incoming tokens could be accepted.");

    ServerSocket serverSocket = new ServerSocket(55555);
    SocketAdapter ca = new SocketAdapter(serverSocket.accept());

    while (!context.isEstablished()) {
        byte[] inToken = ca.readToken();
        byte[] outToken = context.acceptSecContext(inToken, 0, inToken.length);

        if (outToken != null) {
            ca.sendToken(outToken);
        }
    }

    System.out.println("Context established");
    System.out.println("Connected user is: " + context.getSrcName());
    context.dispose();

Configuration du client et code source:
client.conf

Client {
    com.sun.security.auth.module.Krb5LoginModule
        required
        useTicketCache=true
        debug=true;
};

GssClient.java (modèle standard omis)

    GSSManager manager = GSSManager.getInstance();
    GSSName clientName = manager.createName(getClientName(), null);
    GSSCredential clientCred = manager.createCredential(clientName,
                                                        8 * 3600,
                                                        createKerberosOid(),
                                                        GSSCredential.INITIATE_ONLY);
    GSSName serviceName = manager.createName("HTTP/xxx0815.domain.net@DOMAIN.NET", null);

    GSSContext context = manager.createContext(serviceName,
                                               createKerberosOid(),
                                               clientCred,
                                               GSSContext.DEFAULT_LIFETIME);
    context.requestMutualAuth(true);
    context.requestConf(false);
    context.requestInteg(true);

    System.out.println("Establishing context");
    SocketAdapter ca = new SocketAdapter(new Socket("localhost", 55555));

    byte[] inToken = new byte[0];
    while (true) {
        byte[] outToken = context.initSecContext(inToken, 0, inToken.length);

        if (outToken != null) {
            ca.sendToken(outToken);
        }

        if (context.isEstablished()) {
            break;
        }

        inToken = ca.readToken();
    }

    System.out.println("Context established: " + context.isEstablished());

    context.dispose();

J'ai vérifié les données réseau entrantes et sortantes - elles sont identiques des deux côtés, ce qui me permet d'éliminer un problème (j'ai encodé la sortie au format BASE64, puis je l'envoie dans les flux. Je pense qu'il n'y a pas beaucoup cela peut aller mal là-bas ...).

L'exception que je reçois:

Caused by: GSSException: Failure unspecified at GSS-API level (Mechanism level: Integrity check on decrypted field failed (31))
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:741)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:323)
    at sun.security.jgss.GSSContextImpl.acceptSecContext(GSSContextImpl.java:267)
    at de.westlb.mrm.sandbox.gss.GssServer.acceptAndEstablish(GssServer.java:88)
    at de.westlb.mrm.sandbox.gss.GssServer.run(GssServer.java:66)
    ... 4 more
Caused by: KrbException: Integrity check on decrypted field failed (31)
    at sun.security.krb5.internal.crypto.DesCbcEType.decrypt(DesCbcEType.java:154)
    at sun.security.krb5.internal.crypto.DesCbcMd5EType.decrypt(DesCbcMd5EType.java:33)
    at sun.security.krb5.internal.crypto.DesCbcEType.decrypt(DesCbcEType.java:125)
    at sun.security.krb5.internal.crypto.DesCbcMd5EType.decrypt(DesCbcMd5EType.java:33)
    at sun.security.krb5.EncryptedData.decrypt(EncryptedData.java:168)
    at sun.security.krb5.KrbApReq.authenticate(KrbApReq.java:267)
    at sun.security.krb5.KrbApReq.<init>(KrbApReq.java:134)
    at sun.security.jgss.krb5.InitSecContextToken.<init>(InitSecContextToken.java:79)
    at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:724)
    ... 8 more
Était-ce utile?

La solution

Si le contrôle d’intégrité échoue, cela donne à penser que les données ne sont pas envoyées / reçues correctement (message erroné ou incorrect). En d'autres termes, certaines modifications ont eu lieu.

Je sais que vous dites que vous avez vérifié que les données envoyées correspondent aux données reçues au niveau du réseau, mais êtes-vous sûr qu'elles ne sont pas corrompues avant l'envoi ou après la réception? Je vous suggérerais de revoir votre code pour cela en premier.

modifier: en réponse à votre question, un principal de service (en réalité, n'importe quel ticket) peut être lié à une machine spécifique, mais cela se fait normalement en termes d'adresse IP. Dans tous les cas, quelque chose comme ça devrait entraîner une erreur de niveau supérieur différente.

L'erreur que vous obtenez semble avoir des difficultés à décrypter le ticket. Une cause possible de cela est qu'il utilise la mauvaise clé, ce qui peut être lié à la copie de la clé. Le mauvais ticket peut également être à l'origine d'une mauvaise clé (car kerberos fournit essentiellement un protocole de gestion de clé). Est-il possible que vous ayez mis en cache un vieux / ticket incorrect?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top