2012-11-27 88 views
2

所以我是非常新的HMAC認證,我真的不知道我在做什麼,也沒有讀atm。HMAC和WCF服務.net

我一直在試圖正確地理解下面的文章/鏈接/討論:

How to implement HMAC Authentication in a RESTful WCF API

http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/22/how-to-implement-hmac-authentication-on-a-restful-wcf-service.aspx

http://buchananweb.co.uk/security01.aspx

雖這麼說,我有幾個問題:

  1. 瞭解第一個鏈接,例如,如果我有一個在.net中創建的loginAuthentication服務,並且將從iPhone應用程序訪問,我是否會傳遞一個未加密的用戶名(消息),並且應該只返回true/false或應該返回一個加密的字符串,我以後會用於其他事務(刪除,插入服務等)?

    [ServiceContract] 
    
    public partial class LoginService 
    { 
    
    [OperationContract] 
    bool Authenticate(string username) { 
        // stuffs 
    } 
    

    }

  2. 雖這麼說,在我驗證了用戶,而這正是我迷路。 '用時間戳'(有人告訴我這件事,我也讀了一些關於這個的討論)是否更好?或者我只是用加密的消息返回它(取決於第一個問題),以便每次發出請求時已經附加了時間戳?

    a。我該如何處理這個時間戳?

    b。一旦消息被再次發送用於其他交易,它會被使用嗎?

  3. 密鑰和祕密消息。我理解它的方式是密鑰將是用戶的密碼。所以如果用戶發送他的用戶名,我可以使用該用戶的密碼打開郵件?這是有道理的,如果用戶已經有一個會話,並只是要求獲取數據或請求刪除,插入等。如果它只是驗證用戶的用戶名和密碼,是否仍然是相同的方式?

謝謝你的時間!

回答

4

我想提到的第一件事是WCF Web Api是一個不再被開發的測試項目。它被ASP.NET Web API取代,這是一個用於開發RESTful服務的出色框架。

如果您想了解RESTful服務和身份驗證是如何工作的,Netflix API將是一個很好的開始。他們有很多關於安全部分的文檔,這幫助我更多地瞭解HMAC。

HMAC使用密鑰創建哈希。客戶端和服務器都維護密鑰副本,以便它們可以生成匹配的哈希值。這允許你'簽名'作爲認證的雙方的請求(你知道發送它的人是他們說的那個人)以及消息完整性(知道他們發送的消息是原始消息並且沒有被篡改)。

簽名是通過將

1. Timestamp (unix epoc is the easiest to send in urls) 
2. Nonce (a random number that can never be used twice to protect against someone re-using it) 
3. Message (for a GET request this would be the URL, a POST would be the whole body) 
4. Signature (the three previous items combined and hashed using the secret key) 

上述每個可在所述請求中的查詢字符串中被髮送的,則該服務器可以使用該第一3和它們的祕密密鑰的拷貝重新創建簽名。如果簽名匹配,那麼一切都很好。

在一個基於普通HTTP(不是通過SSL使用HTTPS)的RESTful API中,我會簽署每個發送的請求,因爲它再次驗證並提供了消息完整性。否則,如果您只是發送身份驗證令牌,則您知道用戶已通過身份驗證,但如果您沒有消息摘要(HMAC哈希)要與之比較,您如何知道該消息未被篡改?

實現服務器端簽名檢查的簡單方法是重寫OnAuthorization for System.Web.Http.AuthorizeAttribute(確保不要使用Mvc autorize屬性)。讓它像使用密鑰一樣在客戶端執行重建簽名,如果它不匹配,則可以返回401。然後,您可以裝飾所有需要使用新的authorize特性進行身份驗證的控制器。

希望這有助於澄清你的一些困惑,並且不會讓水更加渾濁。如果需要,我可以稍後提供一些更具體的例子。

參考文獻:

Netflix的API文檔:http://developer.netflix.com/docs/Security#0_18325(下井有關創建簽名的一部分,他們也有一個鏈接,顯示了創建HMAC簽名的完整.NET示例)

創建HMAC簽名

.NET類http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs

Netflix的API包裝我寫https://bitbucket.org/despertar1318/netflix-api/overview

的ASP.NET Web APIhttp://www.asp.net/web-api

+0

感謝您的回覆!這實際上使事情更清楚一些。雖然如此,我仍然有幾個問題。由於我真的是新的,並嘗試了stepbystep,讓我首先登錄身份驗證首先與iPhone應用程序,調用登錄webservice.I發送用戶名和散列pword.I返回如果它是真或假(驗證),如果這是真的,我保存用戶名和密碼(這將是我的共享密鑰)。現在,如果我登錄後做了交易,讓我們說「/GetAppointmentDetails?apptid=1".How我知道如果請求者是允許看到appt細節?我通過{用戶名} ..? – gdubs

+0

以及驗證他是否是合適的人並且被允許查看約會細節的鑰匙?還是我hmac散列整個URL參數導致「/ GetAppointmentDetails?hmac = kjsodjdkie ....」並將該hmac標記/散列字符串與數據庫進行比較?呃,真的很困惑。 – gdubs

+0

好的,在閱讀netflix API之後,我現在有了一個更好的主意。但是,我的問題是nonce部分,因此,假設我發送了我的用戶名和pword,它返回true(隨機數?),我保存爲鑰匙pword,現在我要求交易「約會」,我會發回我登錄時得到的「nonce」?並返回一個新的「隨機數」,並將這個請求用於下一個請求。我仍然在正確的軌道上? – gdubs

0

反過來

在你的問題......看我傳遞一個未經加密的用戶名(消息),這和應該返回只是一個真/假還是它應該返回一個加密的字符串,以後我將用它來處理其他事務(刪除,插入服務等)?

如果你剛剛返回一個布爾值,那麼你就沒有辦法將驗證請求匹配到後續請求。您需要返回某種認證指示符,在經典網站上這將是會話cookie,在您想要傳遞將用作共享密鑰的值的實例中。

更好的是,我用數據庫'保存了一個時間戳'嗎?或者我只是將它與加密消息一起返回,以便每次發出請求時都會附加時間戳?

回到會話的類比,你想從問題1的某個地方(數據庫?)存儲密鑰和時間戳,該時間戳指示會話的壽命/密鑰的有效性。如果它是永久的,那麼我不會打擾時間戳,如果它是其他任何事情,當它到期時需要說明什麼。

我理解它的方式是,密鑰將是用戶的密碼。所以如果用戶發送他的用戶名,我可以使用該用戶的密碼打開郵件?這是有道理的,如果用戶已經有一個會話,並只是要求獲取數據或請求刪除,插入等。如果它只是驗證用戶的用戶名和密碼,是否仍然是相同的方式?

這是發生HMAC的地方。你有你的共同祕密,你有一個消息,這是我通常如何將它們結合在一起。

將所有消息用作待散列數據的主體(這樣可以確保某人不僅複製散列和消息的一部分)。使用我們在步驟一中共享的密鑰散列消息的正文。如果想要的話,你可以使用這個用戶名。

最後確保消息中包含時間戳(UTC優先),這樣可以幫助您防止以後重播消息。對消息作出響應的服務可以將時間戳與其認爲的時間進行比較。如果它超出了給定的範圍,則失敗該消息。因爲時間戳將成爲HMAC的一部分,所以有人不能只更新日期並重播消息,只要消息被篡改,哈希就不會匹配。