程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> php實現RSA加密類實例

php實現RSA加密類實例

編輯:關於PHP編程

     這篇文章主要介紹了php實現RSA加密類,實例分析了php自定義RSA類實現加密與解密的技巧,非常具有實用價值,需要的朋友可以參考下

       

    本文實例講述了php實現RSA加密類。分享給大家供大家參考。具體分析如下:

    通過openssl實現的簽名、驗簽、非對稱加解密,需要配合x.509證書(如crt和pem)文件使用。
    由於各種原因,該類並不十分完善,歡迎各種測試!

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 <?php /** * RSA算法類 * 簽名及密文編碼:base64字符串/十六進制字符串/二進制字符串流 * 填充方式: PKCS1Padding(加解密)/NOPadding(解密) * * Notice:Only accepts a single block. Block size is equal to the RSA key size! * 如密鑰長度為1024 bit,則加密時數據需小於128字節,加上PKCS1Padding本身的11字節信息,所以明文需小於117字節 * * @author: linvo * @version: 1.0.0 * @date: 2013/1/23 */ class RSA{ private $pubKey = null; private $priKey = null; /** * 自定義錯誤處理 */ private function _error($msg){ die('RSA Error:' . $msg); //TODO } /** * 構造函數 * * @param string 公鑰文件(驗簽和加密時傳入) * @param string 私鑰文件(簽名和解密時傳入) */ public function __construct($public_key_file = '', $private_key_file = ''){ if ($public_key_file){ $this->_getPublicKey($public_key_file); } if ($private_key_file){ $this->_getPrivateKey($private_key_file); } } /** * 生成簽名 * * @param string 簽名材料 * @param string 簽名編碼(base64/hex/bin) * @return 簽名值 */ public function sign($data, $code = 'base64'){ $ret = false; if (openssl_sign($data, $ret, $this->priKey)){ $ret = $this->_encode($ret, $code); } return $ret; } /** * 驗證簽名 * * @param string 簽名材料 * @param string 簽名值 * @param string 簽名編碼(base64/hex/bin) * @return bool */ public function verify($data, $sign, $code = 'base64'){ $ret = false; $sign = $this->_decode($sign, $code); if ($sign !== false) { switch (openssl_verify($data, $sign, $this->pubKey)){ case 1: $ret = true; break; case 0: case -1: default: $ret = false; } } return $ret; } /** * 加密 * * @param string 明文 * @param string 密文編碼(base64/hex/bin) * @param int 填充方式(貌似php有bug,所以目前僅支持OPENSSL_PKCS1_PADDING) * @return string 密文 */ public function encrypt($data, $code = 'base64', $padding = OPENSSL_PKCS1_PADDING){ $ret = false; if (!$this->_checkPadding($padding, 'en')) $this->_error('padding error'); if (openssl_public_encrypt($data, $result, $this->pubKey, $padding)){ $ret = $this->_encode($result, $code); } return $ret; } /** * 解密 * * @param string 密文 * @param string 密文編碼(base64/hex/bin) * @param int 填充方式(OPENSSL_PKCS1_PADDING / OPENSSL_NO_PADDING) * @param bool 是否翻轉明文(When passing Microsoft CryptoAPI-generated RSA cyphertext, revert the bytes in the block) * @return string 明文 */ public function decrypt($data, $code = 'base64', $padding = OPENSSL_PKCS1_PADDING, $rev = false){ $ret = false; $data = $this->_decode($data, $code); if (!$this->_checkPadding($padding, 'de')) $this->_error('padding error'); if ($data !== false){ if (openssl_private_decrypt($data, $result, $this->priKey, $padding)){ $ret = $rev ? rtrim(strrev($result), "") : ''.$result; } } return $ret; } // 私有方法 /** * 檢測填充類型 * 加密只支持PKCS1_PADDING * 解密支持PKCS1_PADDING和NO_PADDING * * @param int 填充模式 * @param string 加密en/解密de * @return bool */ private function _checkPadding($padding, $type){ if ($type == 'en'){ switch ($padding){ case OPENSSL_PKCS1_PADDING: $ret = true; break; default: $ret = false; } } else { switch ($padding){ case OPENSSL_PKCS1_PADDING: case OPENSSL_NO_PADDING: $ret = true; break; default: $ret = false; } } return $ret; } private function _encode($data, $code){ switch (strtolower($code)){ case 'base64': $data = base64_encode(''.$data); break; case 'hex': $data = bin2hex($data); break; case 'bin': default: } return $data; } private function _decode($data, $code){ switch (strtolower($code)){ case 'base64': $data = base64_decode($data); break; case 'hex': $data = $this->_hex2bin($data); break; case 'bin': default: } return $data; } private function _getPublicKey($file){ $key_content = $this->_readFile($file); if ($key_content){ $this->pubKey = openssl_get_publickey($key_content); } } private function _getPrivateKey($file){ $key_content = $this->_readFile($file); if ($key_content){ $this->priKey = openssl_get_privatekey($key_content); } } private function _readFile($file){ $ret = false; if (!file_exists($file)){ $this->_error("The file {$file} is not exists"); } else { $ret = file_get_contents($file); } return $ret; } private function _hex2bin($hex = false){ $ret = $hex !== false && preg_match('/^[0-9a-fA-F]+$/i', $hex) ? pack("H*", $hex) : false; return $ret; } }

    測試demo:

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php header('Content-Type:text/html;Charset=utf-8;'); include "rsa.php"; echo '<pre>'; $a = isset($_GET['a']) ? $_GET['a'] : '測試123'; ////////////////////////////////////// $pubfile = 'E:sslcertpwd.crt'; $prifile = 'E:sslcertpwd.pem'; $m = new RSA($pubfile, $prifile); $x = $m->sign($a); $y = $m->verify($a, $x); var_dump($x, $y); $x = $m->encrypt($a); $y = $m->decrypt($x); var_dump($x, $y);

    希望本文所述對大家的php程序設計有所幫助。

    1. 上一頁:
    2. 下一頁:
    Copyright © 程式師世界 All Rights Reserved