OPA APIはHMAC(Hash-based message authentication code)認証を使ってしており、マーチャントはHMAC認証を使用してこれらのAPIを呼び出す必要があります。 HMAC認証は、ハッシュ関数と組み合わせてキーを使用するメッセージ認証コードです。 HMACベースの認証の実装では、認証オブジェクトを構築するために要求全体が考慮されます。 クライアント(マーチャント)は、以下のドキュメントに基づいてHMAC認証コードを作成し、HTTP Authorizationリクエストヘッダーに設定します。 要求を受信すると、サーバー(OPA)はこの認証コードを再作成し、両方のコードが一致する場合は要求が正常に実行されます。一致しない場合は、不正な応答が返されます。
Value | Description | Example |
---|---|---|
API Key | PayPayから発行されたAPI Key | APIKeyGenerated |
API Key secret | PayPayから発行されたAPI Key Secret | APIKeySecretGenerated |
Request URI | リクエストURL path | /v2/codes |
Request method | HTTPメソッド | POST |
Epoch | 現在のエポックタイムスタンプ(秒単位), Note : サーバ時刻との差が2分未満である必要があります。 | 1579843452 |
Nonce | ランダムに生成された文字列。Note : 任意の文字列、length 8を推奨。 | acd028 |
Request body | リクエストで渡されるbody。 | {"sampleRequestBodyKey1":"sampleRequestBodyValue1","sampleRequestBodyKey2":"sampleRequestBodyValue2"} |
Request content type | リクエストヘッダーで渡されるコンテンツタイプ。 | application/json;charset=UTF-8; |
hash (MD5(Request body, Request content type)) | リクエストの本文とコンテンツタイプのハッシュ。以下に記載されているStep1で生成されます。 | 1j0FnY4flNp5CtIKa7x9MQ== |
これらから生成されるサンプルHMAC Authヘッダーは以下の通りです。
hmac OPA-Auth:APIKeyGenerated:NW1jKIMnzR7tEhMWtcJcaef+nFVBt7jjAGcVuxHhchc=:acd028:1579843452:1j0FnY4flNp5CtIKa7x9MQ==
Step 1: MD5アルゴリズムを使用してbodyとcontent-typeをハッシュ化する
サンプルコード
private String requestBody;
private String contentType;
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(contentType.getBytes(StandardCharsets.UTF_8));
md.update(requestBody.getBytes(StandardCharsets.UTF_8));
String hash = new String(
Base64.getEncoder().encode(md.digest()),
StandardCharsets.UTF_8);
Note : HTTP GETメソッドの場合など、リクエストの本文がない場合、MD5を生成する必要はありません。代わりに、hashには"empty"がセットされます。
Step 2 : HMAC-SHA256でハッシュ化される文字列を生成します。
リクエストの署名には、以下のパラメータが必要です。
private String requestUrl; //Only the request URI Example: "/v2/codes/payments/dynamic-qr-test-00002"
private String httpMethod;
private String nonce; //Random string
private String epoch;
private String contentType;
private String hash; //Output of step 1
private static final String DELIMITER = "\n";
byte[] hmacData = new StringBuilder()
.append(requestUrl)
.append(DELIMITER)
.append(httpMethod)
.append(DELIMITER)
.append(nonce)
.append(DELIMITER)
.append(epoch)
.append(DELIMITER)
.append(contentType)
.append(DELIMITER)
.append(hash != null ? hash : "")
.toString()
.getBytes(StandardCharsets.UTF_8);
Note : HTTP GETメソッドの場合など、リクエストの本文がない場合、content-typeおよびhashには"empty"がセットされます。
Step 3 : Step2で生成された値と、Key secretを使用してHMACオブジェクトを生成します。
public final String toBase64HmacString() {
private String apiKeySecret;
private byte[] dataToSign; //Output from step 2
try {
SecretKeySpec signingKey = new SecretKeySpec(apiKeySecret.getBytes(StandardCharsets.UTF_8),
"HmacSHA256");
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
sha256HMAC.init(signingKey);
byte[] rawHmac = sha256HMAC.doFinal(dataToSign);
return java.util.Base64.getEncoder().encodeToString(rawHmac);
} catch (GeneralSecurityException e) {
LOGGER.error("Unexpected error while creating hash: " + e.getMessage());
throw new IllegalArgumentException(e);
}
}
Step 4 : ヘッダーオブジェクトを生成します。
String authHeader = "hmac OPA-Auth:" + api-key +
":" + macData + ":" + nonce + ":" + epoch + ":" + hash;
Note: macDataはStep3で生成された値を使用してください。また、nonceとepochは、Step2で使用した値を渡す必要があります。
HTTP GETメソッドの場合などリクエストの本文がない場合、hash値は"empty"となるため、ヘッダーオブジェクトは下記の通りとなります。
String authHeader = "hmac OPA-Auth:" + api-key +
":" + macData + ":" + nonce + ":" + epoch + ":empty";
authHeaderの値を、HttpHeader.AUTHORIZATIONにセットして渡してください。 PayPay側で渡ってきたデータをデコードし、SHA256( "key"、requestParams)を再作成します。 再作成したmacDataとヘッダーで渡ってきた値が一致しているかを検証します。