生活随笔
收集整理的這篇文章主要介紹了
PHP-RSA加密跨域通讯实战
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
PHP-RSA加密跨域通訊實(shí)戰(zhàn) AUTH:PHILO EMAIL:lijianying12 at gmail.com
基于POST GET 的http通訊雖然非常成熟,但是很容易被人監(jiān)聽(tīng)。 并且如果使用跨域jsonp的通訊很容易在歷史記錄中發(fā)現(xiàn)通訊網(wǎng)址以及參數(shù)。為了克服這些問(wèn)題, 并且降低服務(wù)器成本,我們沒(méi)有使用SSL而使用 RSA加密。文章中的php加密解密 JS的加密解密 互相加密解密 都能驗(yàn)證通過(guò)。
其中PHP依賴常見(jiàn)的OPENSSL LIB 。 JS依賴 jsencrypt。
我們使用jsonp get RSA加密通訊好處如下:
前后分離適合cdn加速。 安全跨域更適合松散結(jié)構(gòu)的網(wǎng)站。 不用去買(mǎi)ssl證書(shū)了。
首先要生成密匙對(duì) openssl genrsa 1024 > private . key openssl rsa - in private . key - pubout > public . key JS的RSA加密流程 下載最新版本請(qǐng)移步到github:jsencrypt?代碼在目錄BIN下面是否用壓縮的根據(jù)情況決定。
生成KEY var keySize = 1024 ; //加密強(qiáng)度 var crypt = new JSEncrypt ({ default_key_size : keySize }); //RSA 操作對(duì)象 //方法1 (async) crypt . getKey ( function () { crypt . getPrivateKey (); crypt . getPublicKey (); }); //方法2: crypt . getKey (); crypt . getPrivateKey (); crypt . getPublicKey (); 客戶端加密場(chǎng)景: var crypt1 = new JSEncrypt (); //新建rsa對(duì)象 var publickey = '\ -----BEGIN PUBLIC KEY-----\ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC3N8LJFqlsa6loCgFpgZVMr/Sx\ DMQY7pr0euNQfh2g+UVPbB0MGhoc7nWL0FQhCgDedbjQw/nGFStFx7W1+0o1oRTY\ u5ebNVivZSobraUv7LJvwT8O66Zs8cxbKLqQ/nE/WwJvXomSIckH6R8iOUO8/QT9\ kv6/L0Uma3qA07pmDQIDAQAB\ -----END PUBLIC KEY-----\ ' ; crypt1 . setPublicKey ( publickey ); //添加來(lái)自服務(wù)端的publickey crypt1 . encrypt ( 'abc' ); //返回值為加密后的結(jié)果 客戶端解密場(chǎng)景: var privatekey = '-----BEGIN RSA PRIVATE KEY-----\ MIICXQIBAAKBgQC3N8LJFqlsa6loCgFpgZVMr/SxDMQY7pr0euNQfh2g+UVPbB0M\ Ghoc7nWL0FQhCgDedbjQw/nGFStFx7W1+0o1oRTYu5ebNVivZSobraUv7LJvwT8O\ 66Zs8cxbKLqQ/nE/WwJvXomSIckH6R8iOUO8/QT9kv6/L0Uma3qA07pmDQIDAQAB\ AoGBAKba3UWModbfZXQeSJLxNCqWw9zJp3ydL/keQQ35DLqgyIJAD2QKEWXvtJUT\ sMo19fyicSGOmFXQyYvPCKkmpLkOMAj1XaNpSMtSrcMx+gC01PO6Ey9rsUxW1g3u\ fpqbEk9E3a5AtCS0I61nbUpRL6rqMtR5o2wcNR3TLtJt7pjxAkEA7hlFJKU1zWGp\ OvvkJDnHc2NOCEJoGjqCR9wwv96+/xAykl2laI6WvEbbhjoO0+8+d17oigjhneS5\ 2UKFcfqw7wJBAMT+MCQ5TYLQlvjrBaDMqOdLsqtaDE6CpkrgwV820QMvHOo3R4Xd\ uSbrA2tOr9t2/x+FzF971lRGdPFIch9UYMMCQQCZtO6SDaWCBP3++gX57OL5dq41\ XsldxU+9nERMWTvr5UUAgDv8F7Dvsr6dFHXmE5i77yUnlzwvdi0UOIF1Z2U5AkBV\ wyRKYPgx34Ya0JcerntKV1Zt60I4XADx0G/feAn/DN/VyENHMISPQPm4GgXN0jy4\ CJQ1bcCd6B65fQTSRvXpAkA2Vv5yXzeKDls/AyxHEoros/VYftVc1HOFC++q13Rw\ NH2rnlRT8FMTFEqL9MYRqvvYAFf5VmH0M1Nx5t4LRN+l\ -----END RSA PRIVATE KEY-----\ ' ; var crypt2 = new JSEncrypt (); //新建加密對(duì)象 crypt2 . setPrivateKey ( privatekey ); //給加密對(duì)象設(shè)置privatekey crypt2 . getPublicKey (); //Tip 我們是不需要存儲(chǔ)publickey的直接用private能得到publickey crypt2 . decrypt ( "MeUqWB5LwTh8crzPqbZtEtKuZxYvPWH9CTCChK1qoBzIgIXGPCdzNMbiH0cCYHl5qWSERIDOgDIgv4dXsIMjEJ5q0cp/qNQYHM5va0iw0UvKvQB1E8aWtY2nFEPy4F+ArQ0Mj/ijr/CntEP1jHKC3WU9nu2kYrBIBnbj14Bs+kI=" ); //調(diào)用解密方法 但是雖然寫(xiě)到了這里,加密方面還是不夠用,因?yàn)?024長(zhǎng)度的RSA加密最多只能加密長(zhǎng)度為117的字符串。而URL長(zhǎng)度最多為4k因此這里我們要讓加密長(zhǎng)度達(dá)到2691以達(dá)到能用的程度。 那么這種加密長(zhǎng)度大概能容納多少數(shù)據(jù)呢? 我們借助json-generator來(lái)幫忙生成JSON
sdata =[ { "_id" : "542f9ac2359c7d881bc0298e" , "index" : 0 , "guid" : "db1dacc1-b870-4e3c-bc1a-80dfd9506610" , "isActive" : false , "balance" : "$1,570.15" , "picture" : "http://placehold.it/32x32" , "age" : 36 , "eyeColor" : "blue" , "name" : "Effie Barr" , "gender" : "female" , "company" : "ZORK" , "email" : "effiebarr@zork.com" , "phone" : "+1 (802) 574-3379" , "address" : "951 Cortelyou Road, Wikieup, Colorado, 4694" , "about" : "Sunt reprehenderit do laboris velit qui elit duis velit qui. Nostrud sit eiusmod cillum exercitation veniam ad sint irure cupidatat sunt consectetur magna. Amet nisi velit laboris amet officia et velit nisi nostrud ipsum. Cupidatat et fugiat esse minim occaecat cillum enim exercitation laboris velit nisi est enim aute. Enim do pariatur\r\n" , "registered" : "2014-05-08T15:26:35 -08:00" , "latitude" : 48.576424 , "longitude" : 146.634137 , "tags" : [ "esse" , "proident" , "quis" , "consectetur" , "magna" , "tempor" , "anim" ], "friends" : [ { "id" : 0 , "name" : "Trisha Cannon" }, { "id" : 1 , "name" : "Todd Bullock" }, { "id" : 2 , "name" : "Eileen Drake" }, { "id" : 3 , "name" : "Ferrell Kelly" }, { "id" : 4 , "name" : "Fischer Blankenship" }, { "id" : 5 , "name" : "Morales Mann" }, { "id" : 6 , "name" : "Brandie Pittman" }, { "id" : 7 , "name" : "Virgie Kerr" } ], "greeting" : "Hello, Effie Barr! You have 1 unread messages." , "favoriteFruit" : "apple" }, { "_id" : "542f9ac21c260d03e763a4f2" , "index" : 1 , "guid" : "9e3a3d8a-26f8-46b7-aca0-336a194808b1" , "isActive" : true , "balance" : "$3,617.89" , "picture" : "http://placehold.it/32x32" , "age" : 31 , "eyeColor" : "brown" , "name" : "Butler Best" , "gender" : "male" , "company" : "SPORTAN" , "email" : "butlerbest@sportan.com" , "phone" : "+1 (905) 428-3046" , "address" : "798 Joval Court, Wanship, Delaware, 8974" , "about" : "Nostrud occaecat id sunt pariatur ad nisi do veniam sit officia non consequat amet fugiat. Est eiusmod labore ut cillum qui eu elit ut eiusmod exercitation. Ut anim nostrud eiusmod voluptate tempor proident id do pariatur. In Lorem ullamco ea irure adipisicing. Quis est dolor ex commodo aliqua nisi elit sit elit anim fugiat sunt amet. Enim consequat ipsum occaecat ipsum tempor deserunt dolor veniam nostrud. Anim cillum ullamco cupidatat aute velit fugiat sit enim in amet anim mollit dolor eiusmod.\r\n" , "registered" : "2014-08-02T06:15:44 -08:00" , "latitude" : - 20.529765 , "longitude" : 2.396578 , "tags" : [ "consequat" , "enim" , "magna" , "sunt" , "Lorem" , "quis" , "commodo" ], "friends" : [ { "id" : 0 , "name" : "Kenya Rice" }, { "id" : 1 , "name" : "Hale Knowles" }, { "id" : 2 , "name" : "Michael Stephens" }, { "id" : 3 , "name" : "Holder Bailey" }, { "id" : 4 , "name" : "Garner Luna" }, { "id" : 5 , "name" : "Alyce Sawyer" }, { "id" : 6 , "name" : "Rivas Owens" }, { "id" : 7 , "name" : "Jan Petersen" } ], "greeting" : "Hello, Butler Best! You have 8 unread messages." , "favoriteFruit" : "banana" } ] ?
表單json能達(dá)到這么長(zhǎng)已經(jīng)是很極端的情況了。因此這種方法絕對(duì)是夠用的。
長(zhǎng)表單內(nèi)容加解密方法: function encrypt_data ( publickey , data ) { if ( data . length > 2691 ){ return ;} // length limit var crypt = new JSEncrypt (); crypt . setPublicKey ( publickey ); crypt_res = "" ; for ( var index = 0 ; index < ( data . length - data . length % 117 )/ 117 + 1 ; index ++) { var subdata = data . substr ( index * 117 , 117 ); crypt_res += crypt . encrypt ( subdata ); } return crypt_res ; } function decrypt_data ( privatekey , data ) { var crypt = new JSEncrypt (); crypt . setPrivateKey ( privatekey ); datas = data . split ( '=' ); var decrypt_res = "" ; datas . forEach ( function ( item ) { if ( item != "" ){ de_res += crypt . decrypt ( item );} }); return decrypt_res ; } ?##########NextPage[title=]##########
PHP的RSA加密 php加密解密類 首先要檢查phpinfo里面有沒(méi)有openssl支持
class mycrypt { ? public $pubkey ; public $privkey ; ? function __construct () { $this -> pubkey = file_get_contents ( './public.key' ); $this -> privkey = file_get_contents ( './private.key' ); } ? public function encrypt ( $data ) { if ( openssl_public_encrypt ( $data , $encrypted , $this -> pubkey )) $data = base64_encode ( $encrypted ); else throw new Exception ( 'Unable to encrypt data. Perhaps it is bigger than the key size?' ); ? return $data ; } ? public function decrypt ( $data ) { if ( openssl_private_decrypt ( base64_decode ( $data ), $decrypted , $this -> privkey )) $data = $decrypted ; else $data = '' ; ? return $data ; } ? } 密匙文件位置問(wèn)題,是放到訪問(wèn)接口的附近就可以了如果是CI的話就放到index.php旁邊就行了。 ?但是要注意一點(diǎn),一定要做訪問(wèn)設(shè)置,不然key會(huì)暴出來(lái)的,那時(shí)候信息一旦截獲就慘了。
類的使用 $rsa = new mycrypt (); echo $rsa -> encrypt ( 'abc' ); echo $rsa -> decrypt ( 'W+ducpssNJlyp2XYE08wwokHfT0bm87yBz9vviZbfjAGsy/U9Ns9FIed684lWjYyyofi/1YWrU0Mp8vLOYi8l6CfklBY=' ); 長(zhǎng)數(shù)據(jù)加密解密 function encrypt_data ( $publickey , $data ) { $rsa = new mycrypt (); if ( $publickey != "" ){ $rsa -> pubkey = $publickey ; } $crypt_res = "" ; for ( $i = 0 ; $i <(( strlen ( $data ) - strlen ( $data )% 117 )/ 117 + 1 ); $i ++) { $crypt_res = $crypt_res .( $rsa -> encrypt ( mb_strcut ( $data , $i * 117 , 117 , 'utf-8' ))); } return $crypt_res ; } function decrypt_data ( $privatekey , $data ) { $rsa = new mycrypt (); if ( $privatekey != "" ){ // if null use default $rsa -> privkey = $privatekey ; } $decrypt_res = "" ; $datas = explode ( '=' , $data ); foreach ( $datas as $value ) { $decrypt_res = $decrypt_res . $rsa -> decrypt ( $value ); } return $decrypt_res ; } JSONP 跨域通訊 我們經(jīng)過(guò)千辛萬(wàn)苦經(jīng)過(guò)加密終于能做到通訊安全了。 當(dāng)然我們的下一步是通過(guò)JSONP 的get通訊來(lái)實(shí)現(xiàn)跨域通訊啦。 經(jīng)過(guò)測(cè)試:我們的JS中最長(zhǎng)的Case url長(zhǎng)度是3956 在加上跨域url callbac參數(shù),經(jīng)過(guò)測(cè)試正好差20到4095 (一般的URI長(zhǎng)度限制為4K)
$ . ajax ({ type : "get" , async : false , // 設(shè)置同步通訊或者異步通訊 url : "http://22500e31b5a12457.sinaapp.com/ubtamat/getPubKey?c=hknHQKIy3dyeeajyAwZ+raUkV1ezFbgU8zk+54cNQtrcEGozUjXpYhbC6fxz2hCOgp9feIsM1xKJFm5pkAGQ2UcUOc5EJNCAz6L0mXkZbTBmh3PufWxOE7TaicqRCRtZGGNB2qpm2WruXjYg1lPcrPz/rhFZx4DSJvEHkCm7ZU0=......(加密后的結(jié)果太長(zhǎng),省略)" , dataType : "jsonp" , jsonp : "" , }); ?
header ( "Content-type: application/javascript; charset=utf-8" ); $response = "console.log('test response!')" ; $callback = $this -> input -> GET ( 'callback' ); echo $callback . $response ; PHP代碼是CI框架controler中的部分代碼 并且經(jīng)過(guò)了必要的裁剪。 更加細(xì)節(jié)的參數(shù)都放到GET里面就可以了。 處理之后按照上面的形式處理返回值就ok 如果你配置成功了,你將會(huì)在網(wǎng)頁(yè)的控制臺(tái)上看到自己動(dòng)態(tài)的, 或者像我一樣靜態(tài)的控制臺(tái)輸出。 如果要是想獲取數(shù)據(jù)到網(wǎng)頁(yè)的話還是要借助回調(diào)函數(shù) 來(lái)實(shí)現(xiàn)
JSONP跨域獲取通訊結(jié)果 請(qǐng)看下面代碼:
客戶端代碼
var global = null ; function jpc ( result ) { global = result . msg ; } ? $ . ajax ({ type : "get" , async : false , // 設(shè)置同步通訊或者異步通訊 url : "http://22500e31b5a12457.sinaapp.com/ubtamat/getPubKey" , dataType : "jsonp" , jsonp : "jpc" , }); 服務(wù)器端代碼
header ( "Content-type: application/javascript; charset=utf-8" ); $response = "jpc({'msg':123456})" ; $callback = $this -> input -> GET ( 'callback' ); echo $callback . $response ; 此次通訊的結(jié)果會(huì)在jcp當(dāng)中調(diào)用執(zhí)行,并且返回的內(nèi)容會(huì)記錄到 global 變量當(dāng)中。
實(shí)戰(zhàn) 從上文中,我們已經(jīng)找到了整個(gè)加密過(guò)程方法了,但是距離實(shí)戰(zhàn)還是有一定距離的。 首先我們實(shí)戰(zhàn)的話需要克服接口比較少,功能比較多,單個(gè)接口維護(hù)用時(shí)比較長(zhǎng)的問(wèn)題。
為了解決上面的問(wèn)題我們做出如下設(shè)計(jì)。
客戶端方面: 設(shè)計(jì)一個(gè)通訊類:只管跟服務(wù)器通訊。別的業(yè)務(wù)什么都不管。
//create connection object. var ConnServ = new Object (); ? ConnServ . tmpResponse = "not initial" ; ? //call back function register slot. ConnServ . CallBackFunction = function (){ console . log ( "call back function set error ! U must set a business call back function!" )}; ? //input only encrypted data!!! //send data to server ConnServ . send = function ( data ) { data = data . replace ( /\+/ g , "$" ); //replace all + as $ $ . ajax ({ type : "get" , async : false , url : "http://22500e317.sinaapp.com/ubtamat?c=" + data , dataType : "jsonp" , jsonp : "jpc" }); return "Send Finish" ; } ? //default call back funcation function jpc ( res ) { ConnServ . tmpResponse = res . msg ; ConnServ . CallBackFunction (); } ? ? //public key store. ConnServ . getpublickey = function () { return "\-" + "----BEGIN PUBLIC KEY----- " + ................................................... "-----END PUBLIC KEY-----" ; } 在上面代碼中請(qǐng)注意,RSA加密過(guò)后的字符串當(dāng)中有一個(gè)非法字符+要轉(zhuǎn)換成其他合法字符發(fā)送到服務(wù)器才可以。 不然參數(shù)會(huì)錯(cuò)誤。 等傳輸?shù)椒?wù)器中自己轉(zhuǎn)換回來(lái)在解密就好了。
服務(wù)器端方面: 首先我們接收到消息之后要對(duì)消息進(jìn)行解密,之后根據(jù)報(bào)文內(nèi)容選擇服務(wù)器上的功能。然后把其他參數(shù)輸入到業(yè)務(wù)類中執(zhí)行即可。 因此我們使用了命令模式來(lái)實(shí)現(xiàn)單一接口的豐富業(yè)務(wù)功能。 其他的我們需要對(duì)CI框架的配置進(jìn)行調(diào)整: 首先global config里面需要調(diào)整 $config['global_xss_filtering'] = FALSE; 因?yàn)槿绻麄鬏斶^(guò)來(lái)的報(bào)文解密不了就直接拋棄不進(jìn)行處理(防止CC攻擊第一層)這樣就從url上防止了攻擊的可能性。 當(dāng)然我們還是沒(méi)有完全避免注入風(fēng)險(xiǎn)這時(shí)我們就需要在業(yè)務(wù)類里面調(diào)用安全模塊:
$this -> security -> xss_clean () 來(lái)實(shí)現(xiàn)第二層的XSS攻擊。這是服務(wù)器端設(shè)計(jì)主要需要說(shuō)的位置。
服務(wù)器獲取數(shù)據(jù)處理全過(guò)程 從get接口獲得參數(shù)c的加密數(shù)據(jù) 對(duì)數(shù)據(jù)進(jìn)行RSA解密。 判斷數(shù)據(jù)包時(shí)間戳。如果超時(shí)直接拋棄(防止從瀏覽器記錄中直接發(fā)送request到服務(wù)器,下面是安全方面的說(shuō)明) 首先如果不修改數(shù)據(jù)只修改時(shí)間戳不可能從截獲的數(shù)據(jù)報(bào)文中實(shí)現(xiàn),因?yàn)樾枰匦录用?#xff0c;如果想得到內(nèi)容需要服務(wù)器上的privatekey解密保證安全 如果數(shù)據(jù)包截獲直接發(fā)送數(shù)據(jù)包在超時(shí)范圍內(nèi)直接獲取數(shù)據(jù)包內(nèi)容,也不能實(shí)現(xiàn)攻擊,因?yàn)樵诳蛻舳擞信R時(shí)RSA密匙對(duì)生成并且在發(fā)送的時(shí)候會(huì)同時(shí)發(fā)送publickey 給服務(wù)器做session的存儲(chǔ)內(nèi)容并且偽裝客戶的客戶端沒(méi)有privatekey所以獲取任何關(guān)于登陸之后的消息根本無(wú)法解析。 對(duì)解密后的數(shù)據(jù)進(jìn)行xss檢查 解析報(bào)文中需要調(diào)用什么功能直接調(diào)用反射得到業(yè)務(wù)類的實(shí)例 調(diào)度業(yè)務(wù)類,并且把得到的參數(shù)賦值給業(yè)務(wù)執(zhí)行函數(shù)的參數(shù)。 服務(wù)器處理數(shù)據(jù)過(guò)程只跟業(yè)務(wù)有關(guān) 服務(wù)器返回?cái)?shù)據(jù)全過(guò)程 業(yè)務(wù)處理完成之后針對(duì)每一個(gè)用戶的登陸情況對(duì)返回值進(jìn)行加密。 response 以上業(yè)務(wù)涉及的部分代碼(給出的代碼未涉及以上說(shuō)的安全部分。) //CI 控制器里面的方法 public function index () { header ( "Content-Type: text/html;charset=UTF-8" ); $callback = $this -> input -> GET ( 'callback' ); $input_data = str_replace ( "$" , "+" , $this -> input -> GET ( 'c' )); $input_data = $this -> rsa -> decrypt_data ( $input_data ); if ( $input_data == "" ){ return ;} //如果數(shù)據(jù)不對(duì)解析就會(huì)失敗,直接拋棄數(shù)據(jù)包,避免cracker構(gòu)造數(shù)據(jù)包問(wèn)題 //這里插入時(shí)間戳檢查代碼 //這插入xss檢查 $output_data = command ( $input_data ); $response = "jpc({'msg':" . $output_data . "})" ; $callback = $this -> input -> GET ( 'callback' ); echo $callback . $response ; } ?
//命令模式中的業(yè)務(wù)調(diào)度方法 function command ( $input ) { try { $obj_input = json_decode ( $input ); $action = $obj_input -> { "action" }; $business_action = new ReflectionClass ( $action ); $instance = $business_action -> newInstanceArgs (); $output = $instance -> Action ( $obj_input ); //對(duì)output變量進(jìn)行rsa加密 return "'" . $output . "'" ; // here only accept string } catch ( Exception $e ) { return "'" . $e -> getMessage (). "'" ; } } ?
以下是配合業(yè)務(wù)進(jìn)行的工具函數(shù): //命令接口定義 interface ICommand { function Action ( $arg_obj ); } //把此函數(shù)放到system/core/common.php //實(shí)現(xiàn)了輸入一個(gè)文件夾就自動(dòng)加載所有文件夾中的所有的類。 if ( ! function_exists ( 'require_once_dir' )) { function require_once_dir ( $path ) { $dir_list = scandir ( $path ); foreach ( $dir_list as $file ) { if ( $file != ".." && $file != "." ) { require_once ( $path . "/" . $file ); } } } } ? //使用: //在application/config/autoload.php中添加類似如下代碼: require_once_dir ( APPPATH . "/controllers/lib" ); require_once_dir ( APPPATH . "/controllers/actions" ); 以下是實(shí)現(xiàn)業(yè)務(wù)的例子: class register implements ICommand { public function Action ( $arg_obj ) { return "we are do nothing: " . json_encode ( $arg_obj ); } } 通過(guò)以上基本方法,我們可以實(shí)現(xiàn),只要業(yè)務(wù)繼承我們聲明的接口就可以開(kāi)始寫(xiě)業(yè)務(wù)了。 別的什么都不用管,專注于業(yè)務(wù)即可,其他的安全、IO等問(wèn)題都已經(jīng)一并解決。 并且每一個(gè)業(yè)務(wù)都進(jìn)行了rsa加密xss攻擊過(guò)濾偽造數(shù)據(jù)包攻擊。 以及在response加密只能是固定客戶端才能看到報(bào)文內(nèi)容的全過(guò)程。 但是一定要注意一點(diǎn),注冊(cè)這個(gè)業(yè)務(wù)后面要嵌套登陸進(jìn)行,不然看不到返回值。
數(shù)據(jù)包必須包含的要素: acton (業(yè)務(wù)名) req_time (請(qǐng)求時(shí)間) public_key (如果是注冊(cè)跟登陸時(shí)候需要提交臨時(shí)公匙) 總結(jié) 因?yàn)闀r(shí)間倉(cāng)促所以只能寫(xiě)到這里了。 如果您發(fā)現(xiàn)了我文章中的bug歡迎發(fā)email批評(píng)指正。非常感謝! 同時(shí)本方案也會(huì)成為我們開(kāi)源社區(qū)linux52.com后臺(tái)系統(tǒng)中的接口設(shè)計(jì)方案。 當(dāng)然我們社區(qū)所有維護(hù)的文檔都會(huì)進(jìn)行反復(fù)驗(yàn)證,如果出問(wèn)題我們會(huì)及時(shí)更新。 以維護(hù)文檔的正確性。 點(diǎn)擊=這=里=查看文檔最新版本。
原文發(fā)布時(shí)間:2014-10-11
本文來(lái)自云棲合作伙伴“l(fā)inux中國(guó)”
總結(jié)
以上是生活随笔 為你收集整理的PHP-RSA加密跨域通讯实战 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。