Pergunta

No momento eu estou recebendo um KrbException: verificação de integridade no campo descriptografado falhou (31) com a minha aplicação de demonstração GSS (no lado do servidor). Agora eu estou procurando a razão para isso. Tenho a suspeita, que se trata do fato de que

  1. o cliente eo aplicativo de servidor executado na mesma máquina (localhost) e / ou
  2. o SPN foi gerado por uma outra máquina (computador)

O segundo meio, que o principal de serviço foi gerado por um xxx0815.domain.net máquina, de modo que o SPN é HTTP/xxx0815.domain.net@DOMAIN.NET. E a minha máquina não é essa, mas eu tenho o arquivo keytab para que método de login do servidor bem-sucedido.

Eu suspeito corretamente ou estou fazendo outro erro?

configuração do servidor e código fonte:
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 (omitido o material clichê)

    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();

A configuração do cliente e código fonte:
client.conf

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

GssClient.java (clichê omitido)

    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();

Eu verifiquei os dados da rede de entrada e saída - é o mesmo em ambos os lados para que eu possa descartar um problema lá (eu BASE64-codificado a saída e, em seguida, basta enviá-lo através dos fluxos Eu acho que não há muito. que pode dar errado lá ...).

A exceção que eu recebo:

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
Foi útil?

Solução

Se a verificação de integridade falhar que sugere que os dados não estão sendo enviadas / recebidas corretamente (que ou esta é uma mensagem de erro incorreta). Em outras palavras ocorreu alguma modificação.

Eu sei que você diz ter verificado que os dados enviados coincide com os dados recebidos no nível da rede, no entanto você tem certeza que não está corrompido antes de enviar, ou após o recebimento? Eu sugiro que você revise seu código para este primeiro.

edit: Em resposta à sua pergunta, a principal de serviço (realmente, qualquer bilhete) pode ser ligado a uma máquina específica, mas isso é normalmente feito em termos de endereço IP. Em qualquer caso algo como isso deve resultar em um erro de nível superior diferente.

O erro que você está recebendo soa como ele está tendo problemas para descriptografar o bilhete em primeiro lugar. Uma possível causa disso é que ele está usando a tecla errada, o que pode estar relacionado ao seu copiar o keytab. A chave errada também pode ser causada pelo uso do bilhete errado (como Kerberos basicamente fornece um protocolo de gerenciamento de chaves). É possível que você tenha armazenado em cache um bilhete velho / incorreta?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top