使用滾動程式碼作為不斷變化的共享密鑰對簽名有效嗎?
我是普通的開發人員,正在尋找一些與加密相關的指導。
我試圖確保收到的消息來自特定的發件人,但不需要對消息內容進行加密。發送者和接收者被允許使用一次性安全通道來建立共享秘密。我不想使用完整的加密庫進行消息簽名,因為我的接收者目標受眾包括在低端共享主機上執行的網站,這些庫的訪問權並不總是可用。我想知道是否只需要消息簽名並允許預先共享的秘密足以將問題簡化到可以在我自己的程式碼中安全地解決的問題。
我見過的一種方法是簡單地將共享秘密附加到消息中,將散列函式應用於消息+秘密,並將散列函式的輸出與消息一起作為其簽名發送。我認為這很好,只是它會受到重放攻擊,這對我的應用程序來說是個問題。
如果我不使用靜態共享密鑰,而是使用一次性安全通道在兩端播種 PRNG,將 PRNG 的目前輸出附加到每條消息作為散列函式的輸入,並在每次經過驗證的通信後在兩端推進 PRNG ,這可能有效嗎?我知道還需要對所使用的散列函式和 PRNG 做出明智的選擇,但首先,這種高級方法是否有任何致命的缺陷,我作為一個普通的開發人員無法理解?
編輯
既然一直有熱烈的反應,讓我再分享一點。首先,我不需要相信非對稱密鑰解決方案的好處,我試圖傳達的問題是我自己沒有用腳本語言實現一個,我根本無法訪問 OpenSSL/OpenSSH/ GNUPG 或任何其他能夠在 100% 需要執行的系統上使用公鑰/私鑰的東西。我保證 SHA-256 和其他散列算法和 HMAC 在 100% 需要執行的系統上。
該應用程序作為執行 Drupal 的網站和另一個類似的內容管理系統以及 CMS 組織的伺服器之間的消息傳遞系統,以便為組織提供一種將官方安全更新推送到站點的方法。完整詳情:https ://github.com/mbaynton/cms-autoupdate-design. FWIW,我確實計劃使用 OpenSSL 簽名自行發送安全程式碼更改,但這只會使管理員使 OpenSSL 可用於 php 的站點受益。MAC 基本上是備份,因此沒有 OpenSSL 的站點仍然可以保證更新包的真實性。如果共享秘密數據庫遭到破壞,這本身就會大大降低共享秘密數據庫的價值……您可能會影響到您幾乎浪費時間嘗試的少數站點。
對於這種伺服器間 Web 服務應用程序,需要預共享密鑰的解決方案非常普遍,我將引用http://docs.aws.amazon.com/general/latest/gr/signing_aws_api_requests.html。這樣做可能是一個更好的主意……
我對您的建議感到困惑,即您的客戶將無法訪問公鑰簽名設施,因為您假設他們具有加密雜湊並且可以執行您的作者身份的程式碼。更一般地說,你試圖推出自己的加密貨幣這一事實並不是好兆頭。
另外,我建議您仔細研究一下使用“一次性安全通道”與使用者建立共享密鑰的想法所暗示的挑戰。例如,當您的一位使用者告訴您他們的密鑰已被洩露時會發生什麼?使您自己的該密鑰副本無效很容易,但現在您需要(據說是“一次性”)安全通道再次建立一個新通道。這樣做的代價和不便是什麼?
或者更糟糕的是,想像一下您的預共享密鑰數據庫被洩露的情況。然後,您必須一次與每個使用者建立一個新的共享密鑰。哎喲。
將其與 GitHub 使用公鑰加密來管理對使用者儲存庫的訪問的方式進行比較:
- 使用者在自己的電腦上生成私鑰/公鑰對。
- 使用者使用傳統的使用者身份驗證機制(例如密碼、安全令牌、SMS 等)登錄網站
- 然後,使用者可以上傳公鑰,或刪除他們之前上傳的公鑰。
請注意在這種情況下您獲得了什麼:
“自助服務”:使用者可以隨意添加和刪除密鑰。現在,當您的使用者的密鑰被洩露時,他們只需登錄到您的站點,刪除被洩露的密鑰並上傳新的。
從未通過網路傳輸任何密鑰。這意味著您永遠不會在自己身邊儲存任何密鑰,因此,如果您的公鑰數據庫被披露,這沒什麼大不了的。
您確實需要使用者身份驗證系統,但是:
- 這可以外包(想想所有允許您使用 Google 或 Facebook 憑據登錄的網站);
- 即使您在內部建構了一個,具有強大的使用者密碼和適當的密碼儲存,那麼您的密碼數據庫的破壞可能比共享密鑰數據庫的破壞性要小得多。
但為了解決您的狹隘問題,我會提出兩個意見。首先,您的
hash(message + secret)
方案不安全。閱讀HMAC,這是一種使用散列函式作為消息驗證碼的標準且安全的方法。其次,您可以通過將計數器合併到您計算 MAC 的消息中來避免重放攻擊。不需要隨機數;每個客戶端只跟踪他們從另一方收到的最新消息編號,並拒絕編號早於最新消息的消息。
一個好的 MAC 可以防止偽造。看到消息和標籤(但不是密鑰)的攻擊者…
tag[1] = HMAC(key, rand[1] + message[1]) . . . tag[n] = HMAC(key, rand[n] + message[n])
…將無法偽造有效的
fake_tag = HMAC(key, rand[n+1] + fake_messsage)
即使他們可以預測
rand[n+1]
。RNG 輸出的不可預測性讓你一無所獲。您所需要的只是一種發現回放的方法——計數器就可以了。