WebサービスにパブリックAPIを実装しているところです。お金が関わるため、セキュリティは重要な関心事です。
APIリクエストでユーザーを「認証」する現在の一般的な方法は、メッセージの信頼性を確認し、リクエストごとにユーザーにパラメーターのHMAC(一意のナンスを含む)を送信させることです。
これは問題ありませんが、共有シークレットを使用しています。HMACを生成するには、サーバーとクライアントの両方が秘密鍵を保存する必要があります。
私はこれが好きではありません。暗号化されていない共有シークレットをデータベースに格納し始める場合、パスワードをソルト/ハッシュするすべてのフープラに行く意味は何ですか?
もっと良い方法はありますか?私はGPGを使用することを考えていました。ユーザーに自分のGPG公開キーを提供して保存してもらいました。その後、秘密鍵を使用してメッセージに署名できます。しかし、これはWindowsユーザーが操作するのが少し面倒なことかもしれません。
一般的に、公開/秘密鍵署名はこれを行うためのはるかに良い方法ではありませんか?誰もが共有秘密のHMACを選択している理由がいくつかあるに違いありません...何が欠けていますか?
もちろん、APIを介して顧客とのやり取りに制限を設定し、通知を提供し、システムからお金を取り除くことを制限しますが、共有秘密が漏洩した場合でも、多大な損害が発生する可能性があります。
公開鍵暗号化は低速であり、小さい共有秘密と同じ暗号強度を取得するには、より多くのリソースが必要です。
参照: https://stackoverflow.com/questions/4299795/why-public-key-algorithms-are-slow
少量のシステムを構築している場合、これはおそらく問題にはなりませんが、大規模なシステムになったら、組織と顧客/クライアントに追加のコストを正当化する必要があるかもしれません。
対称シークレットの保存が心配な場合は、おそらくそれを暗号化する必要があります。
私は昨日同じ質問をしましたが、その間に私は私たちの両方の質問に答えると信じているものを見つけました:SRP。 この質問 は、これまでに見つけた最良の答えです。 これはSRPへの参照です 。 SRPの主な問題は、アプリケーションレベルで使用できる最新の実装がないことです。
編集して私の研究からさらに情報を追加します。
データベースを使用するセッションストアを使用することを決定したので、ステートレスの定義を満たしています。これには、SSLが通信のための唯一のプロトコルである必要があり、これによりMITMおよびリプレイ攻撃が排除されます。
私は妥協し、クライアント側Cookieを使用するExpress-jsの安全なセッションストレージを使用しましたが、Cookieはすべてのアプリケーションサーバーが知っている共有シークレットで署名されているため、Cookieは一意ではないというステートレスの定義を満たしていますCookieがまだアプリサーバーのドメインにあるため、クライアントが接続しているサーバーに
user26802は正解です。答えは速度です。 Amazon SQSのようなAPIで、クライアントが大量の小さなメッセージを高速でドロップおよびピックアップし、クライアントでの暗号化とサーバーでの復号化が遅いと、そのサービスの速度が大幅に低下します。
クライアントが秘密鍵署名で認証された呼び出しを行い、短期対称鍵を確立する混合アプローチを想像できます。キーが危険にさらされた場合、キーの有効期限が切れるまでの脆弱性はわずかです。これで、攻撃者がシステムに永続的にアクセスできるようになったとしても、それ以上のことはできません。
覚えておかなければならないもう1つのことは、攻撃者がキーストアを危険にさらし、すべての署名キーを盗むことができる場合、それらは公開キーを置き換えるための位置にあり、別のユーザーとしてリクエストを作成できる可能性があります。