軟件的分佈確實是問題的癥結所在。散列用戶名和密碼並將它們存儲在軟件中並不比存儲未哈希值更有用,因爲任何人都可以訪問API服務器。如果您要爲用戶實現用戶名和密碼,我認爲您可以將它用作API控件的前導,而不必將值存儲在軟件本身中。讓我分兩部分來描述這一點。
請求籤名
在使用API請求驗證的最常用的方法是請求籤名。基本上,在將請求發送到API服務器之前,請求中的參數將被排序,並且將一個唯一密鑰添加到混合中。整個批次將被用於生成一個散列,並附加到請求中。例如:
public static function generateRequestString(array $params, $secretKey)
{
$params['signature'] = self::generateSignature($params, $secretKey);
return http_build_query($params,'','&');
}
public static function generateSignature($secretKey, array $params)
{
$reqString = $secretKey;
ksort($params);
foreach($params as $k => $v)
{
$reqString .= $k . $v;
}
return md5($reqString);
}
你可以創建一個使用上面的代碼只需調用generateRequestString()
方法與你想發送的所有參數的數組的API請求的查詢字符串。祕密密鑰是唯一提供給API的每個用戶的東西。通常,您將用戶ID與簽名一起傳遞到API服務器,並且API服務器使用您的ID從本地數據庫獲取您的密鑰,並使用您構建它的相同方式驗證請求。假設密鑰和用戶標識是正確的,那麼該用戶應該是唯一能夠生成正確簽名的人。請注意,密鑰從未在API請求中傳遞。
不幸的是,這需要每個用戶都有一個唯一的關鍵,這是爲您的桌面應用程序的一個問題。這導致我步驟二。
臨時密鑰
所以你不能與應用程序分發密鑰,因爲它可以被反編譯,並且鍵會全身而退。爲了反制這一點,你可以製作非常短命的鑰匙。
假設你已經實現了桌面應用程序,要求用戶輸入他們的用戶名和密碼的一部分,可以讓應用程序執行的認證請求到服務器。在成功的身份驗證中,您可以返回臨時密鑰和響應,然後桌面應用可以在授權會話的生存期內存儲這些響應,並用於API請求。因爲您提到您無法使用SSL,所以此初始身份驗證是最容易受到攻擊的部分,您必須忍受一些限制。
文章安迪Ë建議是一個好方法(我投它)。基本上是建立一個可用於認證的短期密鑰的握手。相同的密鑰可以用於簽名散列。你也可以抓住機會,只發送未加密的用戶名/密碼並獲得臨時密鑰(它只會發生一次),但是你必須意識到它可能被嗅探。
摘要
如果能建立一個時間的會話密鑰,你就不必存儲在可以反編譯客戶端程序什麼。一次發送到您的服務器的用戶名/密碼應該足以確定這一點。一旦擁有該密鑰,就可以使用它在桌面應用程序中創建請求,並驗證API服務器上的請求。
這看起來像我正在尋找的。謝謝! – 2010-02-04 23:41:56