1. 程式人生 > >PHP RSA加密解密

PHP RSA加密解密

今天我來說下如何使用RSA方式進行加密解密

一、生成公鑰和私鑰;

使用OpenSSL就可以,一般Linux和mac有自帶的;windows的可自行安裝;

通過如下命令生成;

注:

RSA非對稱加密內容長度有限制,1024位key的最多隻能加密127位資料,如果加密字串過長請使用2048

momodeMBP:~ momo$ openssl genrsa -out rsa_private_key.pem 1024(去掉1024預設生成的是2048位)
Generating RSA private key, 1024 bit long modulus

.....++++++

............................++++++

e is 65537 (0x10001)

momodeMBP:~ momo$ openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem

momodeMBP:~ momo$ openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

writing RSA key

momodeMBP:~ momo$

第一條命令生成原始 RSA私鑰檔案 rsa_private_key.pem;

第二條命令將原始 RSA私鑰轉換為 pkcs8格式;

第三條生成RSA公鑰 rsa_public_key.pem;

從上面看出通過私鑰能生成對應的公鑰,因此我們將私鑰private_key.pem用在伺服器端,rsa_public_key.pem給客戶端ios、Android、外部合作方;

這裡我們來說下伺服器端的處理方式:

<?php

$private_key=file_get_contents('private_key.pem'); //讀取私鑰

$public_key=file_get_contents('rsa_public_key.pem'); //讀取公鑰

$pi_key =  openssl_pkey_get_private($private_key);//這個函式可用來判斷私鑰是否是可用的,可用返回資源id Resource id

$pu_key = openssl_pkey_get_public($public_key);//這個函式可用來判斷公鑰是否是可用的

$data = 'method=medicool.user.detail&nonce_str=607673&parameters={"test":"2458"}&partnerid=test';//原始資料

echo "private key encrypt:\n";

openssl_private_encrypt($data,$encrypted,$pi_key);//私鑰加密

$encrypted = base64_encode($encrypted);//加密後的內容通常含有特殊字元,需要編碼轉換下,在網路間通過url傳輸時要注意base64編碼是否是url安全的

$encrypted=urlencode($encrypted);

echo $encrypted,"\n"; //輸出私鑰加密後的字串資料

echo "public key decrypt:\n";

openssl_public_decrypt(base64_decode(urldecode($encrypted)),$decrypted,$pu_key);//私鑰加密的內容通過公鑰可用解密出來

echo $decrypted,"\n"; //通過公鑰解密後的字串資料

echo "---------------------------------------\n";

echo "public key encrypt:\n";

openssl_public_encrypt($data,$encrypted,$pu_key);//公鑰加密

$encrypted = (base64_encode($encrypted));

$encrypted=urlencode($encrypted);

echo $encrypted,"\n";//通過公鑰加密後的字串資料

echo "private key decrypt:\n";

openssl_private_decrypt(base64_decode(urldecode($encrypted)),$decrypted,$pi_key);//私鑰解密

echo $decrypted,"\n"; //通過私鑰解密後的字串資料

?>

下面是ios的對接demo:

//獲得篩選標籤
-(void)requesYikuData{

    //隨機生成6位數

    int num = (arc4random() % 1000000);

    NSString * randomNumber = [NSString stringWithFormat:@"%.6d", num];

    NSLog(@"%@", randomNumber);

    //遵循約定,生成簽名

    //JSON轉換之後有回車空格以及中文轉義問題 導致簽名無法驗證

    //文字轉義放在客戶端執行

    NSString * searchName ="頭孢";//搜尋名稱

    int page = 1;//頁碼

    NSString *string =[NSString stringWithFormat:@"{\"cpage\":%d,\"keywords\":\"%@\"}",page,searchName];

    //3.未加密簽名組成字串

    NSString * str1 = [NSString stringWithFormat:@"method=medicool.drug.search&nonce_str=%@&parameters=%@&partnerid=test",randomNumber,string];

    //4;對3字串根據公鑰RSA加密;

    NSString *rsaStr = [RSAEncryptor encryptString:[str1 lowercaseString] publicKey:YIKUPUBLICKEY];

    NSLog(@"RSA加密後字串%@",rsaStr);

    //5;對4結果進行base64_encode

    NSData * encodeData = [rsaStr dataUsingEncoding:NSUTF8StringEncoding];

    //    encodeData = [encodeData base64EncodedDataWithOptions:0];

    NSString *base64Str = [[NSString alloc] initWithData:encodeData encoding:NSUTF8StringEncoding];

    //6;對5結果進行urlencode;

    NSString * signStr =  [RSAEncryptor encodeString:base64Str];

    NSLog(@"urlencode後字串%@",signStr);

    //請求的url

    NSString * urStr = @"http://extratest.cn/Apidrug/medisearch";


    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer.acceptableContentTypes =[NSSet setWithObjects:@"text/html",@"text/plain",@"text/json",@"application/json",nil];

    manager.requestSerializer = [AFHTTPRequestSerializer serializer];

    manager.responseSerializer = [AFHTTPResponseSerializer serializer];

    NSDictionary* URLParameters = @{

           @"cpage":@1,
           @"keywords":@"頭孢",
           @"method":@"medicool.drug.search",
           @"nonce_str":randomNumber,
           @"partnerid":@"test",
           @"sign":signStr,
       };

  NSMutableURLRequest* request = [[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:urStr parameters:URLParameters error:NULL];
 AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request                                                                 success:^(AFHTTPRequestOperation *operation, id responseObject) {                                                       NSLog(@"HTTP Response Status Code: %ld", [operation.response statusCode]);
                                                                            NSLog(@"HTTP Response Body: %@", responseObject);
                                                                            NSDictionary *tempDictQueryDiamond = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil];
                                                                           NSLog(@"%@",tempDictQueryDiamond);
                                                                         } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                                                        NSLog(@"HTTP Request failed: %@", error);
                                                                      }];
    [manager.operationQueue addOperation:operation];
}

Android對接demo:

主專案

package medicool.com.medicool;



import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.widget.ListView;

import android.widget.SearchView;

import android.widget.TextView;


import java.util.HashMap;



public class MainActivity extends AppCompatActivity {

    private final String url = "http://extratest.meditool.cn/Apidrug/medisearch";

    private final String search_method = "medicool.drug.search";



    private SearchView searchView;

    private TextView textView;


    private int cpage = 1;

    private String sign;

    //POST資料

    HashMap<String, String> args_jsondata = new HashMap<>();

    //簽名原資料

    HashMap<String, Object> args_sign = new HashMap<>();



    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);



        /**

         * method 請求方法名

         nonce_str 隨機字串

         partnerid 合作方指定字串

         sign 簽名

         cpage 請求頁碼

         keywords 搜尋關鍵詞

         */

        args_jsondata.put("method", search_method);

        args_jsondata.put("nonce_str", "123456");

        args_jsondata.put("partnerid", Sign.PARTNERID);



        textView = (TextView) findViewById(R.id.textView);

        searchView = (SearchView) findViewById(R.id.searchView);

        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {

            @Override

            public boolean onQueryTextSubmit(String query) {

                if ("".equals(query)) {

                    return false;

                }



                //這裡注意下手動排序,即 醫庫合作約定

                // 1;將業務請求引數名按照字母升序存入陣列

                args_sign.put("cpage", cpage);

                args_sign.put("keywords", query.trim());



                //對args_sign簽名

                try {

                    sign = Sign.getSign(MainActivity.this, search_method, "123456", args_sign);

                } catch (Exception e) {

                    e.printStackTrace();

                }



                //引數補全

                args_jsondata.put("sign", sign);

                args_jsondata.put("cpage", cpage + "");

                args_jsondata.put("keywords", query.trim());



                new Thread(new Runnable() {

                    @Override

                    public void run() {

                        final String result = HttpUtils.getData(url, args_jsondata);

                        runOnUiThread(new Runnable() {

                            @Override

                            public void run() {

                                textView.setText(result);

                            }

                        });

                    }

                }).start();



                return false;

            }


            @Override

            public boolean onQueryTextChange(String newText) {

                return false;

            }

        });

    }

}

Sign類:

package medicool.com.medicool;

import android.content.Context;

import android.net.Uri;

import android.util.Base64;

import org.json.JSONException;

import org.json.JSONObject;

import java.util.HashMap;

import java.util.Map;



public class Sign {

    //固定

    public static final String PARTNERID = "medicoolgandan2017";



    public static String getSign(Context context, String method, String nonce_str, HashMap<String, Object> parameters) throws Exception {

        String sign;

        JSONObject jsonObject = new JSONObject();

        String j_parameters = "";

        //對parameters進行json_encode處理

        try {

            if (parameters != null && !parameters.isEmpty()) {

                for (Map.Entry<String, Object> entry : parameters.entrySet()) {

                    jsonObject.put(entry.getKey(), entry.getValue());

                }

                j_parameters = jsonObject.toString();

            }

        } catch (JSONException e) {

            e.printStackTrace();

        }



        //拼接引數method=$method&nonce_str=$nonce_str&parameters=$parameters&partnerid=$partnerid

        StringBuffer stringBuffer = new StringBuffer();

        stringBuffer.append("method=").append(method + "&").append("nonce_str=").append(nonce_str + "&").append("parameters=").append(j_parameters + "&").append("partnerid=" + PARTNERID);



        //RSA加密

        byte[] bytes = RsaUtils.encryptData(stringBuffer.toString().getBytes(), context);


        //base64_encodec

        sign = Base64.encodeToString(bytes, Base64.DEFAULT);



        //urlencode

        sign = Uri.encode(sign);


        return sign;

    }


}

RsaUtils類:

package medicool.com.medicool;



import android.content.Context;

import android.util.Base64;



import java.io.InputStream;

import java.security.KeyFactory;

import java.security.PublicKey;

import java.security.spec.X509EncodedKeySpec;



import javax.crypto.Cipher;



public class RsaUtils {

    private static String RSA = "RSA";

    private static final String ECB_PKCS1_PADDING = "RSA/ECB/PKCS1Padding";



    public static byte[] encryptData(byte[] data, Context context) {

        byte[] resultBytes = null;

        try {

            PublicKey publicKey = loadPublicKey(context);

            Cipher cipher = Cipher.getInstance(ECB_PKCS1_PADDING);

            cipher.init(Cipher.ENCRYPT_MODE, publicKey);

            resultBytes = cipher.doFinal(data);

        } catch (Exception e) {

            e.printStackTrace();

        }



        return resultBytes;

    }



    private static PublicKey loadPublicKey(Context context) throws Exception {

        try {

            PublicKey publicKey;

            byte[] keyBytes = Base64.decode(readFile(context, "rsa_public_key.pem"), Base64.DEFAULT);

            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);

            KeyFactory keyFactory = KeyFactory.getInstance(RSA);

            publicKey = keyFactory.generatePublic(keySpec);

            return publicKey;

        } catch (Exception e) {

            throw new Exception("金鑰資料讀取錯誤");

        }

    }



    private static String readFile(Context context, String file) {

        int len;

        byte[] buf;

        String grammar = "";

        try {

            InputStream in = context.getAssets().open(file);

            len = in.available();

            buf = new byte[len];

            in.read(buf, 0, len);

            grammar = new String(buf, "utf-8");

        } catch (Exception e) {

            e.printStackTrace();

        }

        return grammar;

    }
}

HttpUtils類:

package medicool.com.medicool;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class HttpUtils {
    public static String getData(String url, HashMap<String, String> params) {

        HttpPost post = new HttpPost(url);

        HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 30000);
httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 30000);
        ArrayList<NameValuePair> paramPairs = new ArrayList<>();
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                paramPairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
        }

        try {
            post.setEntity(new UrlEncodedFormEntity(paramPairs, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            return "";
        }

        try {
            HttpResponse response;
            response = httpclient.execute(post);
            String inf;
            if (response.getStatusLine().getStatusCode() == 200) {// 判斷響應狀態碼
                inf = EntityUtils.toString(response.getEntity());
                return inf;
            }
        } catch (Exception e) {

            e.printStackTrace();
        }
        return "";
    }
}

相關推薦

php rsa加密解密實例 及簽名驗證-自己實踐

date wql bio eee resource haar ted can open <?php /** * Created by PhpStorm. * User: Administrator * Date: 2018/4/1 *

PHP RSA加密解密

今天我來說下如何使用RSA方式進行加密解密 一、生成公鑰和私鑰; 使用OpenSSL就可以,一般Linux和mac有自帶的;windows的可自行安裝; 通過如下命令生成; 注: RSA非對稱加密內容長度有限制,1024位key的最多隻能加密127位資料,如果加密字

php rsa加密解密例項(非對稱加密

php服務端與客戶端互動、提供開放api時,通常需要對敏感的部分api資料傳輸進行資料加密,這時候rsa非對稱加密就能派上用處了,下面通過一個例子來說明如何用php來實現資料的加密解密 1、加密解密的第一步是生成公鑰、私鑰對,私鑰加密的內容能通過公鑰解密(反過來亦可以

php rsa加密解密例項

php服務端與客戶端互動、提供開放api時,通常需要對敏感的部分api資料傳輸進行資料加密,這時候rsa非對稱加密就能派上用處了,下面通過一個例子來說明如何用php來實現資料的加密解密 1、加密解密的第一步是生成公鑰、私鑰對,私鑰加密的內容能通過公鑰解密(反過來亦可以)

RSA加密解密(無資料大小限制,php、go、java互通實現)

RSA加解密中必須考慮到的金鑰長度、明文長度和密文長度問題。明文長度需要小於金鑰長度,而密文長度則等於金鑰長度。因此當加密內容長度大於金鑰長度時,有效的RSA加解密就需要對內容進行分段。這是因為,RSA演算法本身要求加密內容也就是明文長度m必須0<m<金鑰長度n。

利用RSACryptoServiceProvider進行RSA加密解密

rop color ria keyvalue ngs eat splay null crypto 利用RSACryptoServiceProvider進行RSA加密解密 加密獲取公私鑰 static void Main(string[] args)

iOS常用加密RSA加密解密

pen style 工作 eight else mark 分段 load port 前言: iOS常用的加密有很多種,前兩天在工作中遇到了RSA加密,現在把代嗎分享出來。 RSA基本原理 RSA使用"秘匙對"對數據進行加密解密.在加密解密數據前,需要先生成公鑰(publi

php rsa加密解密實例

ssi utf source 實例 print 系統 encrypted 代碼 pre php服務端與客戶端交互、提供開放api時,通常需要對敏感的部分api數據傳輸進行數據加密,這時候rsa非對稱加密就能派上用處了,下面通過一個例子來說明如何用php來實現數據的加密解密

C# Java間進行RSA加密解密交互

exc add 交互 長度限制 orm keys 什麽 highlight arr 引用:http://blog.csdn.net/dslinmy/article/details/37362661 這裏,講一下RSA算法加解密在C#和Java之間交互的問題,這兩天糾結了很久

php加密解密

urldecode ech 項目 mode function encrypt 變化 double printf php加密和解密函數通常可以用來加密一些有用的字符串存放在數據庫裏或作為各個子系統間同步登陸的令牌,並且通過解密算法解密字符串,該函數使用了base64和MD5

C#-java RSA加密解密

過程 data readline utf 解密 param rsa私鑰 convert graph using Org.BouncyCastle.Math;using Org.BouncyCastle.Crypto.Parameters;using Org.BouncyCa

C#自定義RSA加密解密RSA簽名和驗證類實例

狀態 share normal evel thumb weight encrypt security clas 本文實例講述了C#自定義RSA加密解密及RSA簽名和驗證類。分享給大家供大家參考。具體分析如下: 這個C#類自定義RSA加密解密及RSA簽名和驗證,包含了RSA

RSA加密解密及數字簽名Java實現

cto 包括 sign object misc 數據 factory 了解 對稱密鑰 RSA公鑰加密算法是1977年由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)一起提出的。當時他們三人都在

Java使用非對稱數據加密RSA加密解密

ner tco init git turn comm [] 4類 fse   emmmmmm就是呢,我今天研究了一下非對稱數據加密RSA的使用,算法什麽的暫時不研究,加密算法還有很多,以後再研究吧,就醬(>人<;)。非對稱加密算法需要兩個密鑰:公開密鑰(publicKey)

RSA加密解密

ase castle mar class ext 默認 crypto publickey () using System;using System.IO;using System.Security.Cryptography;using System.Text;using M

php aes加密解密類(兼容php5、php7)

bytes pri rip dom ase lee vat idea cipher <?php /** * @desc:php aes加密解密類 * @author [Lee] <[<[email protected]>]> */ class

RSA加密解密實現(JAVA)

1.關於RSA演算法的原理解析參考:http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html 2.RSA金鑰長度、明文長度和密文長度參考:https://blog.csdn.net/liuhuabai100/article/deta

JDK中JCA的簡單使用(三)---RSA加密解密

Cipher 類 Cipher類提供用於加密和解密的加密密碼功能。加密是獲取資料(稱為明文)和 金鑰,並且生成資料(密文)對於不知道金鑰的第三方無意義的過程。解密是一個相反的過程:採用密文和金鑰並生成明文。 對稱與非對稱加密 有兩種主要的加密型別:對稱(也稱為金鑰)和非對稱(或公

RSA加密解密和簽名驗證機制以及其區別和聯絡

https://blog.csdn.net/wangjianno2/article/details/68965299   1.RSA的加密解密機制原理RSA公鑰加密體制包含如下3個演算法:KeyGen(金鑰生成演算法),Encrypt(加密演算法)以及Decrypt(解密演算法)。詳細如下:

條理清晰的入門:使用Java實現RSA加密解密

條理清晰的入門:使用Java實現RSA加密解密 什麼是RSA 使用Java 需要匯入的標頭檔案 生成公鑰、私鑰 進行加密解密 金鑰的儲存 密文的儲存、讀取 什麼是RSA 翻一下以前的密碼