一、準備工做,生成RSA 私鑰 公鑰php
openssl genrsa -out rsa_private_key.pem 1024 openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
第一條命令生成原始 RSA私鑰文件 rsa_private_key.pem,第二條命令將原始 RSA私鑰轉換爲 pkcs8格式,第三條生成RSA公鑰 rsa_public_key.pem 私鑰生成對應的公鑰,咱們將私鑰private_key.pem用在服務器端,公鑰發放給android跟ios等前端html
二、服務器端 PHP前端
require __DIR__.'/ORG/Rsa.class.php'; require __DIR__.'/ORG/MagicCrypt.class.php'; //RSA私匙解密出公鑰加密的AES key $rsaObject = new \V1\ORG\Rsa(); $appkey = $rsaObject->privDecrypt($_POST['rsakey']); $MagicCryptObject = new \V1\ORG\MagicCrypt(); $MagicCryptObject->MagicCrypt($appkey);//用key解密傳輸數據 $username = $MagicCryptObject->decrypt($_POST['username']); $password = $MagicCryptObject->decrypt($_POST['password']); $qtime = $MagicCryptObject->decrypt($_POST['qtime']); if ($qtime - time() > 3600*24) { //return } $member = $this->member->where('username=?', $username)->select(false);//獲取會員 if ($member['password'] == md5(md5($password) . $member['salt'] . md5($password))) {//驗證會員 //生成token,用rsa私鑰加密並返回密文 token規則能夠自定義 $userToken = md5($member['id'].$member['salt'].$appkey); $appAuth['memberid'] = $member['id']; $appAuth['token'] = $userToken; $appAuth['expire'] = time() + 7*24*3600;//7天有效 //存儲或更新token 能夠考慮不一樣存儲 db redis memcached等 $appAuthOld = $this->model('member_appauth')->find($member['id']); if ($appAuthOld) { $this->model('member_appauth')->update($appAuth,array('memberid'),'memberid=' . $member['id']); } else { $this->model('member_appauth')->insert($appAuth); } var_dump($userToken);exit; }
客戶端PHP 模擬 測試用的android
require __DIR__.'/ORG/Rsa.class.php'; require __DIR__.'/ORG/MagicCrypt.class.php'; $appkey = 'myandroid-IEMI-20160101-'.date('YmdHis');//隨機字符串 AES加密用 能夠是根據客戶端設備號/安裝時間/請求時間等生成 $MagicCryptObject = new \V1\ORG\MagicCrypt(); $MagicCryptObject->MagicCrypt($appkey);//用隨機密鑰加密傳輸數據 AES rijndael-128 $post['username'] = $MagicCryptObject->encrypt('ehovel'); $post['password'] = $MagicCryptObject->encrypt('dpx890406???'); $post['qtime'] = $MagicCryptObject->encrypt(time());//客戶端請求時間 服務端用來判斷有效 $rsaObject = new \V1\ORG\Rsa(); $rsakey = $rsaObject->pubEncrypt($appkey);//用rsa公鑰加密 $key $post['rsakey'] = $rsakey; //模擬請求 $url = 'http://www.testlocal.com/index.php?s=sapi&c=user&a=login'; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); //curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15); curl_setopt($ch, CURLOPT_TIMEOUT, 15); $data = curl_exec($ch); $status = curl_getinfo($ch); $errno = curl_errno($ch); curl_close($ch); print_r($data);exit;
客戶端 JAVA ios
參考實現 未測 BASE64 http://git.oschina.net/ehovel/codes/emkrvbhx8oq7c91s4tp3y AES http://git.oschina.net/ehovel/codes/52i4r0zwvkh1cmopngltf RSA http://git.oschina.net/ehovel/codes/2915gjp6t8ih4xkenbqof RSA http://git.oschina.net/ehovel/codes/kcey6uvrhzl79b4tqpwg5
須要注意的是,在初始化Cipher對象時,必定要指明使用"RSA/ECB/PKCS1Padding"格式如Cipher.getInstance("RSA/ECB/PKCS1Padding");打開rsa_public_key.pem文件,將上面代碼的RSA_PUBLICE替換成其中內容便可。git
客戶端 IOS redis
iOS上沒有直接處理RSA加密的API,網上說的大多數也是處理X.509的證書的方法來實現,不過X.509證書是帶簽名的,在php端openssl_pkey_get_private方法獲取密鑰時,第二個參數須要傳簽名,而android端實現X.509證書加密解密較爲不易,在這裏咱們利用ios兼容c程序的特色,利用openssl的api實現rsa的加密解密,代碼以下:api
參考 http://www.lvtao.net/dev/android_ios_php_openssl.html