算法名稱 | 標準名稱 | 備注 |
---|---|---|
RSA2 | SHA256WithRSA | 強制要求RSA密鑰的長度至少為2048 |
RSA | SHA1WithRSA | 對RSA密鑰的長度不限制,推薦使用2048位以上 |
RSA2 比 RSA 有更強的安全能力。
螞蟻金服,新浪微博 都在使用 RSA2 算法。
創(chuàng)建公鑰和私鑰:
openssl genrsa -out private_key.pem 2048
openssl rsa -in private_key.pem -pubout -out public_key.pem
執(zhí)行上面命令,會生成private_key.pem和public_key.pem兩個文件。
示例代碼(類庫):
class Rsa2 { private static $PRIVATE_KEY = 'private_key.pem 內(nèi)容'; private static $PUBLIC_KEY = 'public_key.pem 內(nèi)容'; /** * 獲取私鑰 * @return bool|resource */ private static function getPrivateKey() { $privateKey = self::$PRIVATE_KEY; return openssl_pkey_get_private($privateKey); } /** * 獲取公鑰 * @return bool|resource */ private static function getPublicKey() { $publicKey = self::$PUBLIC_KEY; return openssl_pkey_get_public($publicKey); } /** * 私鑰加密 * @param string $data * @return null|string */ public static function privateEncrypt($data = '') { if (!is_string($data)) { return null; } return openssl_private_encrypt($data,$encrypted,self::getPrivateKey()) ? base64_encode($encrypted) : null; } /** * 公鑰加密 * @param string $data * @return null|string */ public static function publicEncrypt($data = '') { if (!is_string($data)) { return null; } return openssl_public_encrypt($data,$encrypted,self::getPublicKey()) ? base64_encode($encrypted) : null; } /** * 私鑰解密 * @param string $encrypted * @return null */ public static function privateDecrypt($encrypted = '') { if (!is_string($encrypted)) { return null; } return (openssl_private_decrypt(base64_decode($encrypted), $decrypted, self::getPrivateKey())) ? $decrypted : null; } /** * 公鑰解密 * @param string $encrypted * @return null */ public static function publicDecrypt($encrypted = '') { if (!is_string($encrypted)) { return null; } return (openssl_public_decrypt(base64_decode($encrypted), $decrypted, self::getPublicKey())) ? $decrypted : null; } /** * 創(chuàng)建簽名 * @param string $data 數(shù)據(jù) * @return null|string */ public function createSign($data = '') { if (!is_string($data)) { return null; } return openssl_sign($data, $sign, self::getPrivateKey(), OPENSSL_ALGO_SHA256) ? base64_encode($sign) : null; } /** * 驗證簽名 * @param string $data 數(shù)據(jù) * @param string $sign 簽名 * @return bool */ public function verifySign($data = '', $sign = '') { if (!is_string($sign) || !is_string($sign)) { return false; } return (bool)openssl_verify($data, base64_decode($sign), self::getPublicKey(), OPENSSL_ALGO_SHA256); } }
示例代碼:
$rsa2 = new Rsa2(); $privateEncrypt = $rsa2->privateEncrypt('鋤禾日當午'); echo '私鑰加密后:'.$privateEncrypt.'br>'; $publicDecrypt = $rsa2->publicDecrypt($privateEncrypt); echo '公鑰解密后:'.$publicDecrypt.'br>'; $publicEncrypt = $rsa2->publicEncrypt('鋤禾日當午'); echo '公鑰加密后:'.$publicEncrypt.'br>'; $privateDecrypt = $rsa2->privateDecrypt($publicEncrypt); echo '私鑰解密后:'.$privateDecrypt.'br>'; $sign = $rsa2->createSign('鋤禾日當午'); echo '生成簽名:'.$privateEncrypt.'br>'; $status = $rsa2->verifySign('鋤禾日當午', $sign); echo '驗證簽名:'.($status ? '成功' : '失敗') ;
運行結(jié)果:
部分數(shù)據(jù)截圖如下:
JS-RSA
JSEncrypt:用于執(zhí)行OpenSSL RSA加密、解密和密鑰生成的Javascript庫。
Git源:https://github.com/travist/jsencrypt
應(yīng)用場景:
我們在做 WEB 的登錄功能時一般是通過 Form 提交或 Ajax 方式提交到服務(wù)器進行驗證的。
為了防止抓包,登錄密碼肯定要先進行一次加密(RSA),再提交到服務(wù)器進行驗證。
一些大公司都在使用,比如淘寶、京東、新浪 等。
示例代碼就不提供了,Git上提供的代碼是非常完善的。
這些加密技術(shù),能夠達到安全加密效果的前提是密鑰的保密性。
實際工作中,不同環(huán)境的密鑰都應(yīng)該不同(開發(fā)環(huán)境、預(yù)發(fā)布環(huán)境、正式環(huán)境)。
那么,應(yīng)該如何安全保存密鑰呢?
環(huán)境變量
將密鑰設(shè)置到環(huán)境變量中,每次從環(huán)境變量中加載。
配置中心
將密鑰存放到配置中心,統(tǒng)一進行管理。
密鑰過期策略
設(shè)置密鑰有效期,比如一個月進行重置一次。
在這里希望大佬提供新的思路 ~
Postman
一款功能強大的網(wǎng)頁調(diào)試與發(fā)送網(wǎng)頁 HTTP 請求的 Chrome插件。
這個不用多介紹,大家肯定都使用過。
SocketLog
Git源:https://github.com/luofei614/SocketLog
解決的痛點:
SocketLog,可以解決以上問題,它通過WebSocket將調(diào)試日志輸出到瀏覽器的console中。
使用方法
接口開發(fā)完畢,需要給請求方提供接口文檔,文檔的編寫現(xiàn)在大部分都使用Markdown格式。
也有一些開源的系統(tǒng),可以下載并安裝到自己的服務(wù)器上。
也有一些在線的系統(tǒng),可以在線使用同時也支持離線導(dǎo)出。
根據(jù)自己的情況,選擇適合自己的文檔平臺吧。
常用的接口文檔平臺:
一、在 HTTP 和 RPC 的選擇上,可能會有一些疑問,RPC框架配置比較復(fù)雜,明明用HTTP能實現(xiàn)為什么要選擇RPC?
下面簡單的介紹下 HTTP 與 RPC 的區(qū)別。
傳輸協(xié)議:
HTTP 也是 RPC 實現(xiàn)的一種方式。
性能消耗:
推薦一個像 JSON ,但比 JSON 傳輸更快占用更少的新型序列化類庫MessagePack。
官網(wǎng)地址:https://msgpack.org/
還有一些服務(wù)治理、負載均衡配置的區(qū)別。
使用場景:
比如瀏覽器接口、APP接口、第三方接口,推薦使用 HTTP。
比如集團內(nèi)部的服務(wù)調(diào)用,推薦使用 RPC。
RPC 比 HTTP 性能消耗低,傳輸效率高,服務(wù)治理也方便。
推薦使用的 RPC 框架:Thrift。
二、動態(tài)令牌
簡單介紹下幾種動態(tài)令牌,感興趣的可以深入了解下。
OTP:One-Time Password 一次性密碼。
HOTP:HMAC-based One-Time Password 基于HMAC算法加密的一次性密碼。
TOTP:Time-based One-Time Password 基于時間戳算法的一次性密碼。
使用場景:
本文講了設(shè)計簽名驗證需要滿足的一些條件:可變性、時效性、唯一性、完整性。
還講了一些加密方法:單向散列加密、對稱加密、非對稱加密,同時分析了各種加密方法的優(yōu)缺點,大家可以根據(jù)自己的業(yè)務(wù)特點進行自由選擇。
提供了 Aes、Rsa 相關(guān)代碼示例。
分享了可以編寫接口文檔的在線系統(tǒng)。
分享了開發(fā)過程中使用的接口調(diào)試工具。
擴展中分析了 HTTP 和 RPC 的區(qū)別,動態(tài)令牌的介紹等。
以上就是詳解PHP接口簽名驗證的詳細內(nèi)容,更多關(guān)于PHP接口簽名驗證的資料請關(guān)注腳本之家其它相關(guān)文章!