• 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¶meters={"test":"2458"}&partnerid=test';//原始数据
     
    echo "private key encrypt:
    ";
     
    openssl_private_encrypt($data,$encrypted,$pi_key);//私钥加密
     
    $encrypted = base64_encode($encrypted);//加密后的内容通常含有特殊字符,需要编码转换下,在网络间通过url传输时要注意base64编码是否是url安全的
     
    $encrypted=urlencode($encrypted);
     
    echo $encrypted,"
    "; //输出私钥加密后的字符串数据
     
    echo "public key decrypt:
    ";
     
    openssl_public_decrypt(base64_decode(urldecode($encrypted)),$decrypted,$pu_key);//私钥加密的内容通过公钥可用解密出来
     
    echo $decrypted,"
    "; //通过公钥解密后的字符串数据
     
    echo "---------------------------------------
    ";
     
    echo "public key encrypt:
    ";
     
    openssl_public_encrypt($data,$encrypted,$pu_key);//公钥加密
     
    $encrypted = (base64_encode($encrypted));
     
    $encrypted=urlencode($encrypted);
     
    echo $encrypted,"
    ";//通过公钥加密后的字符串数据
     
    echo "private key decrypt:
    ";
     
    openssl_private_decrypt(base64_decode(urldecode($encrypted)),$decrypted,$pi_key);//私钥解密
     
    echo $decrypted,"
    "; //通过私钥解密后的字符串数据
     
    ?>
    

    下面是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=%@¶meters=%@&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¶meters=$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 "";
        }
    }
    
  • 相关阅读:
    C++ reference
    C++ const 限定符
    POJ 1222 EXTENDED LIGHTS OUT(高斯消元)
    poj 2185
    poj 2406
    poj 2752
    hdu 6171
    hdu 6127
    uva 3708
    hdu 6092
  • 原文地址:https://www.cnblogs.com/liuqun/p/12655194.html
Copyright © 2020-2023  润新知