サービスプリンシパル名(SPN)は特定のマシンにバインドされていますか?

StackOverflow https://stackoverflow.com/questions/435091

  •  10-07-2019
  •  | 
  •  

質問

現時点では、KrbExceptionを取得しています:GSSデモアプリケーション(サーバー側)で、復号化されたフィールドの整合性チェックに失敗しました(31)。今、私はこの理由を探しています。疑いがあります。それは、

  1. クライアントとサーバーアプリケーションが同じマシン(localhost)上で実行されているか、
  2. SPNは別のマシン(コンピューター)用に生成されました

2番目は、マシンxxx0815.domain.netに対してサービスプリンシパルが生成されたため、SPNはHTTP/xxx0815.domain.net@DOMAIN.NETであることを意味します。私のマシンはそうではありませんが、サーバーのログインメソッドが成功するようにキータブファイルを取得しています。

正しく疑われるのですか、それとも別の間違いを犯していますか?

サーバー構成とソースコード:
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(定型的なものは省略)

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

クライアントの構成とソースコード:
client.conf

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

GssClient.java(定型句は省略)

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

送信および受信ネットワークデータを確認しました-両方で同じなので、そこで問題を除外できます(出力をBASE64でエンコードしてから、ストリームを介して送信するだけです。間違っている可能性があります...)

私が受け取る例外:

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
役に立ちましたか?

解決

整合性チェックに失敗した場合、データが正しく送受信されていないことが示唆されます(または、これは誤ったエラーメッセージです)。つまり、いくつかの変更が行われました。

送信したデータがネットワークレベルで受信したデータと一致することを確認したと言っていますが、送信前または受信後に破損していないことを確認していますか?最初にこのコードを確認することをお勧めします。

編集:質問への回答として、サービスプリンシパル(実際には、任意のチケット)を特定のマシンにバインドできますが、これは通常IPアドレスの観点から行われます。いずれにせよ、そのような何かが別のより高いレベルのエラーをもたらすはずです。

表示されているエラーは、そもそもチケットの解読に問題があるように聞こえます。考えられる原因は、間違ったキーを使用していることです。これは、キータブのコピーに関連している可能性があります。間違ったキーは、間違ったチケットを使用することでも発生します(Kerberosは基本的にキー管理プロトコルを提供するため)。古い/間違ったチケットをキャッシュした可能性はありますか?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top