2009-01-12 42 views
2

目前我收到KrbException:解密字段的完整性檢查失敗(31)與我的GSS演示應用程序(在服務器端)。現在我正在尋找原因。我有懷疑,它來自一個事實,即是否將服務主體名稱(SPN)綁定到特定計算機?

  1. 客戶端和在同一臺機器上的服務器應用程序運行(本地主機)和/或
  2. 的SPN是爲另一臺機器(計算機)
  3. 產生

第二個意味着服務主體是爲機器xxx0815.domain.net生成的,所以SPN是HTTP/[email protected]。而我的機器不是那個,但我已經獲得了keytab文件,以便服務器的登錄方法成功。

我懷疑是否正確或我犯了另一個錯誤?

服務器配置及源代碼:
server.conf中

Server { 
    com.sun.security.auth.module.Krb5LoginModule 
     required 
     isInitiator=false 
     doNotPrompt=true 
     useKeyTab=true 
     keyTab="gssdemo.keytab" 
     storeKey=true 
     principal="HTTP/[email protected]" 
     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/[email protected]", 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 

回答

1

如果完整性檢查失敗,這表明該數據沒有被髮送/接收正確的(即或這是不正確的錯誤消息)。換句話說,一些修改已經發生。

我知道你說你已經檢查過發送的數據與網絡級別的接收數據是否匹配,但是你確定發送之前或收到之後沒有損壞嗎?我建議你先查看你的代碼。

編輯:在回答你的問題時,服務主體(真的,任何票)都可以綁定到特定的機器上,但這通常是通過IP地址來完成的。在任何情況下,類似的情況都會導致不同的更高級別的錯誤。

您聽到的錯誤聽起來像是無法首先解密票證。可能的原因是它使用了錯誤的密鑰,這可能與複製密鑰表有關。使用錯誤的票證也可能導致錯誤的密鑰(因爲Kerberos基本上提供密鑰管理協議)。你有可能緩存一張舊/不正確的票嗎?

+0

我用數據檢查編輯了部件 - 恐怕沒有太多可以出錯的地方。不過,我仔細檢查一下。但我猜想它會進入keytab/keys方向...... – 2009-01-12 12:43:23

相關問題