目次
1. APIインターフェースの署名が必要なのはなぜですか?
外界に公開されているAPIインターフェースは、マスカレード攻撃、改ざん攻撃、リプレイ攻撃、データ情報漏えいのリスクなど、いくつかのセキュリティ問題に直面します。APIインターフェースの署名を使用すると、これらのセキュリティの問題とリスクを簡単に防ぐことができます。APIインターフェースの署名を設計する際には、次の点を考慮する必要があります。
- 要求されたデータが正しいことを確認してください
リクエストの特定のフィールドの値が変更されると、元の署名結果が変更されます。したがって、パラメータが変更されている限り、署名を変更する必要があります。変更されていない場合、リクエストは無効なリクエストになります。
- リクエストのソースが正当であることを確認してください
通常、署名を生成するアルゴリズムには、appKeyとappSecretのペアがあり、呼び出し元のIDはappKeyに基づいて識別でき、署名が有効かどうかはappSecretに基づいて識別できます。
- インターフェースの適時性を特定する
通常の状況では、署名とパラメーターにタイムスタンプが含まれるため、サーバーはクライアント要求が有効な時間内にあるかどうかを確認できるため、インターフェイスへの長時間の呼び出しを回避できます。
2.APIインターフェース署名検証の実装メカニズム
- 署名検証フローチャート
1クライアントはappKeyとappSecretをサーバーに適用し、サーバーはappKeyとappSecretを発行します。
2クライアントはSDKを統合して署名を生成し、appKey、要求パラメーター、タイムスタンプ、および署名をサーバーに送信します。サーバーはSDKの署名ルールを使用して、要求パラメーターに従って署名を生成し、の有効性を検証します。記号を入力し、結果を返します。
- コード
//签名
public static Map<String, String> generateSign(String appKey, String appSecret, String url, String method) throws NoSuchAlgorithmException, InvalidKeyException {
Map<String, String> headers = new HashMap<String, String>();
SimpleDateFormat df = new SimpleDateFormat(DATE_FORMAT_STRING);
df.setTimeZone(new SimpleTimeZone(0, TIME_ZONE));
String timestamp = df.format(new Date());
StringBuilder stringToSign = new StringBuilder();
stringToSign.append(method.toUpperCase()).append(url).append(timestamp);
String signature = sign(appSecret, stringToSign.toString());
headers.put("signature", signature);
headers.put("appKey", appKey);
headers.put("timestamp", timestamp);
return headers;
}
//验证签名
public static String validateSign(String appSecret, String url, String method, String timestamp) throws NoSuchAlgorithmException, InvalidKeyException {
StringBuilder stringToSign = new StringBuilder();
stringToSign.append(method.toUpperCase()).append(url).append(timestamp);
return sign(appSecret, stringToSign.toString());
}
//签名和验签公用方法
private static String sign(String appSecret, String stringToSign)
throws InvalidKeyException, NoSuchAlgorithmException {
SecretKeySpec signingKey = new SecretKeySpec(appSecret.getBytes(CHARSET), "HmacSHA1");
Mac mac = Mac.getInstance(ALGORITHM_HMAC_SHA1);
mac.init(signingKey);
byte[] data = mac.doFinal(stringToSign.getBytes(CHARSET));
return Base64.getEncoder().encodeToString(data);
}
参照ドキュメント:https://help.aliyun.com/document_detail/101343.html?spm = a2c4g.11186623.6.574.6fa75ffal5uEms