みなさん、こんにちは。私はファラオです。最近プロジェクトを引き継ぎました。大きな仕事をすることに興奮していましたが、侵入テストの後、ほとんど愚かでした。アンチリプレイ攻撃、リクエストボディの改ざん、不正な攻撃はすべて対処されています。まあ、このプロジェクトが過去6か月間どのように費やされたかはわかりません。
誰もがインターフェースのセキュリティについてどう思っているかはわかりませんが、パブリックネットワークにサービスを提供する製品にとって、これは致命的と言えます。では、より安全なインターフェイスアクセスポリシーを設計するにはどうすればよいでしょうか。
1.トークンと署名
一般に、クライアントとサーバーの設計プロセスでは、それらのほとんどがステートフルインターフェイスとステートレスインターフェイスに分けられます。通常、ユーザーがログインすると、ユーザーがアクセス許可を持っているか、インターフェイスを要求できるかは、ユーザーが正常にログインした後にサーバーによって付与されたトークンによって制御されます。ただし、トークンを使用してリクエストが安全であるという意味ではありません。トークンが漏洩した場合はどうなるでしょうか。誰かが私のサービスに電話できますか?
銀行に行ってお金を引き出すのと同じように、銀行カードが必要です。しかし、誤って銀行カードを紛失したからといって、それを見つけた人があなたの銀行カードを銀行に持って行ってビジネスを行うことはできません。彼らはまたあなたの身元を確認する必要があり、あなたはまたあなたの銀行カードのPINを知っている必要があります。
したがって、トークンはユーザー権限とセッションのクレデンシャルにすぎません。セッションのクレデンシャルに加えて、トークンの漏洩によるクライアントの損失を防ぐために、リクエストの有効性も検証する必要があります。
シグニチャダイジェスト計算は、リクエストの有効性を検証するために使用されます。学生はしばしば2つを混同します。トークンを使用しても安全です。
2.署名計算の設計
シグニチャダイジェストの計算は、一般的にシグニチャ値とシグニチャキーに分けられます。シグニチャ生成方法は次のとおりです。
signature = Base64(HMAC-SHA256(LOWER(MD5(key)), StringToSign))
2.1署名文字列のデザイン
シグニチャ文字列を設計するときは、さまざまな攻撃戦略のためにどのような種類のリクエストヘッダーを設計する必要があるかを考える必要があります。
一般的に使用される署名文字列は、次のように設計されています。
StringToSign = Content-MD5 + "\n"
+ CanonicalizedHeaders
CanonicalizedHeadersの構築方法は次のとおりです。
- 次のように、サービスのプレフィックスが付いているが、サービス署名を含まないヘッダー
- service-nonce:クライアントは32ビットのランダムな文字列を生成します。これは5分以内にすべてのクライアントに対して繰り返すことはできません。プラットフォームが繰り返しナンスで応答する場合、クライアントは再要求する必要があります。
- service-date:要求が生成された時刻がサーバーの現地時刻から5分以上離れており、認証が失敗します。
- service-session-id:客户端会话id,用于本次登录后的所有请求会话标识。
- service-client:客户端信息,包括客户端类型、客户端版本、操作系统等。
- Header名称全部小写,值前后应不包含空格
- Header的名称和值之间用“:”相隔,组成一个完整的header
- 根据header名称的字符顺序,将header从小到大进行字典排序
每个header之后跟一个“\n”
StringToSign生成示例
eB5eJF1ptWaXm4bijSPyxw==\n
service-client:ewogICAgImRhdGEiOiB7CiAgICAgICAgImNsaWVudFR5cGUiOiAieHh4IiwKICAgICAgICAiY2xpZW50VmVyc2lvbiI6ICIzLjAiCiAgICB9Cn0=\n
service-date:2022-07-22T14:43:07Z\n
service-nonce:d36e316282959a9ed4c89851497a717f\n
service-session-id:0123456\n
2.3. 签名key设计
一般客户端请求的接口类型有三种,分别是有登录状态和无登录状态以及登录这个特殊接口。无登录状态前的接口都是服务为了提供能力而做的一些接口,相比而言都是提供通用能力的。不涉及客户个人信息相关。安全风险较小。用户登录后的接口一般都是涉及到客户信息的接口,隐私泄露风险较大。因此对于每一种状态可采用不同的key值设计。讲风险降到最低。
2.3.1. 用户未登录签名key值
用户未登录时,平台提供通用能力,调用服务端接口时使用约定好的固定SK进行接口签名鉴权即可。固定SK由后台提供16位的随机字符串。
2.3.2. 用户登录签名key值
我们知道,所有在客户端和前端保存的key值永远不是最安全的,有可能被拆包而发现对应的加密SK,从而被不法分子破解,因此用户登录时,传输密码时,如果使用固定key,有可能body体被解开,密码被泄露的风险。
登录时用户会输入密码,而服务端也知道用户加密后的密码,那么使用用户输入的密码当做key则是最安全的方式。并且交互过程中不需要将用户密码放在body体重传到后端进行校验,只需校验签名的准确性即可。这样就可以极大的增加用户密码的安全性。
用户登录验证时会输入用户的密码,则登录时用户密码作为签名的key进行鉴权校验。加密key为:SHA256(LOWER(MD5(passwd)),salt),salt为用户的盐值,可以使用用户的手机号。
2.3.3. 用户登录签名key值
ユーザーが正常にログインした後、すべてのインターフェースを認証する必要があります。各ユーザーのセキュリティのために、各ユーザーには、ログインが成功した後に取得される独自のSKが発行されます。このようにして、クライアントはセルセットをメモリに保存し、SKリークを効果的に防ぐことができます。
1.ユーザーが正常に登録されると、バックグラウンドでユーザーアカウント用に16ビットのセルセットが生成されます
2.ユーザーが正常にログインすると、バックグラウンドでユーザーのサービスが返されます
3.ログイン後のインターフェース認証では、認証にsercetを使用します。
3.インターフェースの妥当性検証プロセス
リクエストの有効性の検証プロセスは次のとおりです。
1.まず、インターフェースのリクエストヘッダーのナンスが5分以内に繰り返されるかどうかを確認します。これにより、リプレイ攻撃を効果的に防ぐことができます。
2.次に、タイムスタンプを確認して、クライアントの時間改ざん攻撃を防ぎます
3.その後、リクエストのMD5を確認して、リクエストの本文が改ざんされないようにします。
4.最後に、nonce、date、md5、およびsessionで組み合わせた署名検証を実行して、署名値が成功したかどうかを検証します。上記の単一変更検証は合格するが、署名値検証は失敗するという問題を効果的に防ぐことができます。
上記の検証に基づいて、ほとんどの攻撃シナリオは基本的に防ぐことができます。もちろん、セキュリティを強化するために、ブラックリストとホワイトリストの制限、インターフェイスアクセスの現在の制限、ユーザー共通デバイスのバインド、ユーザーのリモートログインなど、ユーザーのプロパティを保護するセキュリティ設計を追加することもできます。
さて、この記事の誰もがセキュリティ設計についてより深く理解しているのだろうか?より優れたインターフェースセキュリティ設計ソリューションがありますか?一緒にチャットできます。
私は、アイデアと含意を持ったエンジニアリングライオンのワン・ラオシです。私に注意を払い、より技術的な知識を学びます。
- ナゲッツテクノロジーコミュニティのクリエイター署名プログラムの募集に参加しています。リンクをクリックして登録し、送信してください。