11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

あと1年ほどでサービスが終了してしまうLINE Pay。

今回焦点を当てたのは、LINE Pay APIの認証方法で使われている「HMAC-SHA256」ハッシュ作成方法です。

この方法を参考にした認証方法をサービスに組み込んだのですが、Google Apps Scriptから利用するときは工夫が必要でしたので、記事を書くことにします。

LINE Pay APIで利用されているハッシュの作り方

Signature = Base64(HMAC-SHA256(Your ChannelSecret, (Your ChannelSecret + URL Path + Query String + nonce))) 

※ Query String : ?を除いたクエリ文字列(例 : Name1=Value1&Name2=Value2...)

サービス用にカスタマイズしたハッシュの作り方

Signature = Base64(HMAC-SHA256(Your ChannelSecret, (Your ChannelSecret + Request Body + nonce))) 

実装したロジック

PHPで実装したクライアント

$ChannelSecretKey = 'secret_key';

$request = ['テスト'];

$nonce = (string)microtime(TRUE);

$payload = json_encode($request, JSON_UNESCAPED_UNICODE);

$message = $ChannelSecretKey.$payload.$nonce;

$signature = base64_encode(hash_hmac('sha256', $message, $ChannelSecretKey , true));

Google Apps Scriptで実装したクライアント
const request = [
    'テスト'
]

const payload = JSON.stringify(request)

const nonce = Date.now().toString()

const data = SECRET_KEY + payload + nonce

const rawSignature = Utilities.computeHmacSha256Signature(data, SECRET_KEY)
const signature = Utilities.base64Encode(rawSignature)
Logger.log('Generated Signature: ' + signature)

沼ったポイント

Google Apps Script(クライアント)からPHP(サーバー)のAPIを呼び出すことを目標としているのですが、
何度Google Apps Scriptでシグネチャを作成しても、PHP側で作成したシグネチャと一致しない。
という問題に直面しました。

「ChatGPT」に質問をしても「問題ない」との一点張りでなかなか解決に向かいませんでした。

判明した原因

$request = ['テスト'];

としていましたが、

$request = ['test'];

にしたら、どうなるのだろうか。

と思い試したところ、シグネチャがPHPクライアントと一致することが確認できました。

つまり実装自体は間違っていなかったことになります。

つまりGoogle Apps Scriptクライアントの挙動が日本語の有無に左右されていたことになります。

今回PHPで作成するシグネチャとGoogle Apps Scriptで作成するシグネチャが一致しない原因として、
内部エンコーディングが一致していないことが原因でした。

PHPは内部エンコーディングがUTF-8だった。
Google Apps Scriptは内部エンコーディングがUTF-8ではなかった。

上記の理由から、シグネチャの作成ロジックを見直すことになりました。

改良版の作成

Google Apps Scriptで実装したクライアント
const request = [
    'テスト'
]

const payload = JSON.stringify(request)

const nonce = Date.now().toString()

const data = SECRET_KEY + payload + nonce

// UTF-8バイト配列に変換
const utf8Data = Utilities.newBlob(data).getBytes() // 追加
const utf8Key = Utilities.newBlob(SECRET_KEY).getBytes() // 追加

const rawSignature = Utilities.computeHmacSha256Signature(utf8Data, utf8Key) // 修正
const signature = Utilities.base64Encode(rawSignature)
Logger.log('Generated Signature: ' + signature)

最後に

Utilities.computeHmacSha256SignatureUtilities.base64Encodeが悪いのだと思い、ライブラリの変更ばかりに目が行っていましたが、理由は単純なものでした。

11
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?