產生HMAC Signature (簽章驗證)
與第三方串接API時,需要加密、MAC來驗證傳輸的內容是否正確沒有被傳輸中途修改過
開始前需要的資料
- KEY:雙方互相加解密的私鑰,第三方會提供一個KEY,通常會 base_64_encode,所以使用時,必須要先decode
- IV:隨機碼,為了每次加密時都是不一樣的內容,避免被暴力破解
如何產生 KEY?
- 請API服務方提供
如何建立 IV?
每次送出Request前產生的IV都會不同,為了避免被攔截查詢,
一些敏感或個資資料,會透過IV來進行加密的動作,接收方再進行解密取得資料
API方會提供產生IV的方法,一並加入Request Body中,透過IV驗證資料是否與MAC一致
建立範例
UUID SHA-256 之後 取前 16 Byte
1
2$uuid = Str::uuid()->toString();
$iv = substr(hash('sha256', $uuid, true), 0, 16);AES-256-CBC 加密
1
2
3
4
5
6
7private function encryptAES256CBC(string $str, string $key, string $iv): string
{
$cipher = 'AES-256-CBC';
$encrypt = openssl_encrypt($str, $cipher, $key, OPENSSL_RAW_DATA, $iv);
return $encrypt;
}AES-256-CBC 解密
1
2
3
4
5
6
7private function decryptAES256CBC(string $data, string $key, string $iv): string
{
$cipher = 'AES-256-CBC';
$decrypt = openssl_decrypt($data, $cipher, $key, OPENSSL_RAW_DATA, $iv);
return $decrypt;
}產生HMAC,文件會標示拿哪一些欄位進行加密檢核,流程大家都不一樣,以下的流程是
- 組合字串進行AES-256-CBC
- 字串 SHA-256 取得 前 16 Byte
- 前 16Byte 轉為字串,轉為全部大寫
1 | $key = 'MmVhMmFlNjMtMWY1Ny00NjAzLTg4ZTUtNjYwMzViZTFkOTUz'; |
- 假設文件產生HMAC的順序為 $uuid + $order_no + $amount
加密前字串組合::bf2b29f6-cd80-4201-8615-7296eb8f74e4TED20230510300.0
注意欄位為非字串的話,可能會在組合時造成字串被忽略,300.0 在組合後會變成300
1 | $uuid = 'bf2b29f6-cd80-4201-8615-7296eb8f74e4'; |
1 | mac = C67FE772002FCCE0 |