假设有一个 api,没有任何身份验证,则所有人都可以调用。
所以进一步,给能调用 api 的客户端下发 client_secert,客户端每次调用 api 时需要携带 sha1(client_secert),即 signature,这样,没有 client_secert 的人就不能调用了。
但如果黑客截获了该 signature,仍然可以随意调用 api。
所以再进一步,signature=sha1(client_secert, timestamp),即将时间戳作为 salt 来计算 signature,调用 api 时携带 signature 和 时间戳。
服务器也用相同的方式算出 signature,这样就相当于不但验证了 client_secert 是否正确,还验证了客户端请求 api 时携带的时间戳和算出 signature 的那个时间戳是否相同。另外,还要验证该时间戳和服务器当前系统时间差距大不大,如果差距太大(如超过 10s 或 少 10s),就不予调用成功。
这种方式可以一定程度防止重放攻击,黑客如果想调用 api,截获+修改+转发的时间不能超过 10s。
注意:要求服务器和客户端时间必须是标准时间。
如果黑客真的能在 10s 内完成截获+修改+转发,为了进一步降低危害,可以将 uri 甚至请求参数全部用来计算 signature,即 signature=sha1(uri+params+timestamp, client_secert),此时 uri+params+timestamp 更像是被加密的内容,而 client_secert 像是加密密钥(当然也可以理解为 salt)。这样,黑客相当于只能调用指定的 api 而不能调用其他 api,且请求参数也是固定的。
这种方法的作用也可以理解为防止黑客篡改客户端想进行的操作。