android、ios等客戶端與PHP服務端驗證登錄,加密通訊

kongweb 8年前發布 | 24K 次閱讀 Android開發 移動開發

來自: http://my.oschina.net/u/1987422/blog/624893


1、準備工作,生成RSA 私鑰 公鑰

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等前端

2、服務器端 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 模擬 測試用的

            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.dmibz-local.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 

參考實現 未測
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替換成其中內容即可。

客戶端 IOS 

iOS上沒有直接處理RSA加密的API,網上說的大多數也是處理X.509的證書的方法來實現,不過X.509證書是帶簽名的,在php端openssl_pkey_get_private方法獲取密鑰時,第二個參數需要傳簽名,而android端實現X.509證書加密解密較為不易,在這里我們利用ios兼容c程序的特點,利用openssl的api實現rsa的加密解密,代碼如下:

參考 http://www.lvtao.net/dev/android_ios_php_openssl.html


 本文由用戶 kongweb 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!