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 "";
    }
}

 

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,那我来给你简单地介绍一下 Vue 中使用 jsrsasign 进行 RSA 加密,以及 PHP 中如何使用 jsrsasign 进行 RSA 解密的方法。 首先,你需要在 Vue 项目中安装 jsrsasign 库。可以通过 npm 安装: ``` npm install --save jsrsasign ``` 接下来,在 Vue 组件中引入 jsrsasign 库: ```js import * as jsrsasign from 'jsrsasign'; ``` 然后,你可以使用 jsrsasign 库中的 RSA 加密方法进行加密: ```js const publicKey = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxWq8GIV2n8B0vzgW/9f0\n9f8sokUeMv2kEX0VtL0X+gP+3Z6z8gfk1C0yRd4XnFqT+qfQexJgNQ+6N0lR5t57\nU0BuK7pM6hBcG/auDnTJH5k1ElL6wZaZP3ZwI+o9uZp4t9N4z0QFpQ/2kQGvN9Kv\n/y5Gc0kjM+Lw6J8QHbS3WbiH+OfkD6TwHs3Sv3XrQux6OvD4lSfJtA5pxzXs7pcq\n5X1EaVQq1Gd/5yG9vNzK4+Yx+2j5hJ3bhfJ+o7bLZieVUAyjy3DkGnBfrtD+LQ+3\n2wX8A2ZVd5H/3T3Kd+JyXpVxwX1m8lO5+Ih3vz5IbJfT9dAJWS5jQbT1t6w3OzQ\n1QIDAQAB\n-----END PUBLIC KEY-----"; const encrypt = (text) => { const publicKeyObj = jsrsasign.KEYUTIL.getKey(publicKey); const encrypted = jsrsasign.KJUR.crypto.Cipher.encrypt(text, publicKeyObj); return jsrsasign.hextob64(encrypted); }; ``` 这里的 `publicKey` 是你的 RSA 公钥字符串, `encrypt` 方法用于加密传入的文本。 接下来,我们来看看在 PHP 中如何使用 jsrsasign 进行 RSA 解密。首先,你需要在 PHP 项目中引入 jsrsasign 库: ```php require_once('jsrsasign.php'); ``` 然后,你可以使用 jsrsasign 库中的 RSA 解密方法进行解密: ```php use \phpseclib\Crypt\RSA; $privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD9r0L2CpkLq0XJ\n..."; $ciphertext = "..."; $rsa = new RSA(); $rsa->loadKey($privateKey); $plaintext = $rsa->decrypt(jsrsasign\ASN1::hex2bin($ciphertext)); ``` 这里的 `privateKey` 是你的 RSA 私钥字符串, `ciphertext` 是加密后的密文字符串。`plaintext` 是解密后的原文字符串。 希望这个简单的例子能够帮到你。如果有任何问题,欢迎继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值