Day 7 - 使用 AES-CBC 机制对 Message 内文进行加密

图 7-1
图 7-1: 各栏位资料范例

本文的目标是将如 Message 栏位的内文使用 AES 加密机制将其进行加密,并转换成如上图所示的 16 进制字串。

AES 加密机制

在笔者本身串接各家金流的经验中,AES (advanced encryption standard) 区块加密法最常见到的,其中加密模式又以 ECB 与 CBC 使用频率最高。ECB 是最简单的加密模式,不需要 IV 值,大部分厂商在安全要求更严谨的资料上会使用 CBC 加密模式。

本系列的永丰金收款系统正是使用 CBC 加密模式。

CBC 加密模式需要一个初始化向量 (initialization vector) 来对其第一个区块加盐,也就是我们在 Day 6 产生的 IV 值。

依赖套件

在 PHP 中使用 AES-CBC 加密模式是使用 openssl_encrypt 函式,如果执行时发生找不到函式的错误,可以先使用 php -m 指令确认一下有无安装 OpenSSL 扩展。如果没有的话则必须先安装唷!

图 7-2
图 7-2: CLI 指令范例 php -m

如上图红箭头标示,找到的话表示您的 PHP 版本已安装 OpenSSL。

加密实作

在使用 openssl_encrypt 函式时有三个参数我们必须提供。请见以下说明。

Message 加密要件

图 7-3
图 7-3: Message 栏位要件,文件第 22 页

(1) JSON 讯息内文

图 7-4
图 7-4: 范例 - 建立订单的资料结构

JSON 讯息内文为要传送给 API 的资料结构,作为 openssl_encrypt 函式的第一个参数。

(2) HashId

openssl_encrypt 函式的第三个参数,作为加密的 key。
取得方法参阅 Day 3 - 安全签章: HashId 计算

(3) IV

openssl_encrypt 函式的第四个参数。
取得方法参阅 Day 6 - 产生内文加密所需的 IV 值

范例

图 7-5
图 7-5: PHP SDK - aesEncrypt 方法

本范例是 PHP SDK 中用来进行 AES-CBC 加密的方法。

第13行 为使用 PHP 函式 openssl_encrypt 进行加密。
第14行 将加密後产生的 binary string 转成 HEX,接着转成大写字元。

验证加密结果

图 7-6
图 7-6: 加密测试网页

API 文件第 22 页提供两个线上测试工具来验证加密是否正确。

网址
加密 https://sandbox.sinopac.com/QPay.ApiClient/Calc/Encrypt
解密 https://sandbox.sinopac.com/QPay.ApiClient/Calc/Descrypt

在笔者进行线上工具测试时,发现程序的加密程序码算出来的结果和线上测试工具的结果不同,再进一步比对输入的 JSON 字串,发现必须要一模一样,多一个空格、断行或者跳脱字元都不行。

例如,单纯使用 json_encode 函式将阵列转换成 JSON 字串时,中文字会被编码,反斜线也被加了跳脱字元,因此在测试的时候可以考虑以下两个方法之一:

(1) json_encode 加上旗标

可以在 json_encode 函式加上旗标值让 JSON 字串的输出和我们贴到测试网页的一致,不然加密後的结果会不一样喔!

关於 json_encode 的旗标值可参阅 PHP 官方手册 这一页

图 7-7
图 7-7: json_encode 加上 flag 差异

上图是使用 json_encode 将阵列转成 JSON 字串有无使用旗标的差异,标市示绿色萤光色是中文字被转成 Unicode 编码字符,标市示黄色萤光色是反斜线也被加了跳脱字元。经由此图可以一眼看出其中的差别。

常数名 旗标值 说明 
JSON_UNESCAPED_UNICODE 256 不把中文字转成 Unicode 编码字符
JSON_UNESCAPED_SLASHES 64 不把反斜线加上跳脱字元 \
JSON_FORCE_OBJECT 16 会把空阵列 [] 转成 {}

以上是一些可以参考使用的旗标常数,总而言之,程序转出来的 JSON 字串要和网页上的一样就对了。

(2) 使用程序产生的 JSON 字串

另外一个方法是,使用程序产生的 JSON 字串贴到测试网页上的输入框。虽然中文字被转码,也会有跳脱字元,不过只要两边的字串是完全一致,加密後的结果就会一样。

流程总结

今天的文章完成了发送请求给 Order API 需要的 Message 栏位,其它需要的栏位也已取得,明天的进度就来建立我们第一笔的测试订单吧!


本文更新於笔者的 TerryL 部落格,Day 7 - 使用 AES-CBC 机制对 Message 内文进行加密,有兴趣可前往阅读及讨论。


<<:  【7】Dataset 的三个API : Shuffle Batch Repeat 如果使用顺序不同会产生的影响

>>:  EP09 - 建立 Django 专案和 EC2 环境 并手动部署到 EC2

【PHP 设计模式大头菜】模板方法 Template Method

模板方法 Template Method 模板方法,是一种如果这包水泥我有、你也有,就连乔瑟夫都有...

Day25. Blue Prism让你远离挑灯夜战的日子 –BP自动登打订单

昨天加班加的凶, 到现在为止都还在挑灯夜战, 不过,在不景气的日子人就要想着变通, 才会有机会的到来...

【Day 20】 实作 - 於 AWS Quicksight 建立 Sankey diagram 以及设定 Action

昨天我们已经透过 AWS Glue Job 来调整 Partition 分区结构以及将此格式转换成 ...

行政调查(administrative investigation)

-证据大图 行政调查是内部调查。 调查(Investigation) 调查:调查或研究,检查与某事...

【Day 26】情境模拟:再好看也没用 !? 设计稿被工程师说太难做不出来 QQ

接下来,会就六角学院 UI 设计入门 课程中,针对团队合作时会碰到的情境稍作讨论。 设计稿再好看也没...