zoukankan      html  css  js  c++  java
  • RSA加密传输代码示例

    RSA加密传输代码示例

    涉及敏感数据的传输,双方最好约定使用加密解密。那RSA非对称加密就大有作为了。
    服务端可以保留自己的私钥,发给客户端对应的公钥。这样就可以互相加解密了。php中rsa加解密实现:

    首先要生成一对公钥私钥。前提是linux机器上安装了openssl命令。

    生成私钥文件:

    1openssl genrsa -out rsa_private_key.pem 1024

    利用私钥,生成公钥:

    1openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

    php代码案例:

     1<?php
    2ini_set('error_reporting', -1);
    3ini_set('display_errors', -1);
    4header('Content-Type: text/html; charset=utf-8');
    5
    6$private_key = file_get_contents("/home/users/xx/test/rsa_private_key.pem");
    7$public_key = file_get_contents("/home/users/xx/test/rsa_public_key.pem");
    8
    9$pi_key = openssl_pkey_get_private($private_key);// 可用返回资源id
    10$pu_key = openssl_pkey_get_public($public_key);
    11
    12// 加密数据
    13$data = array(
    14    'id' => '1234567890',
    15    'name' => '小明',
    16    'mobile' => '123456',
    17);
    18// 转换为JSON格式
    19$data = json_encode($data);
    20
    21$encrypted = '';
    22$decrypted = '';
    23
    24
    25// 公钥加密
    26openssl_public_encrypt($data, $encrypted, $pu_key);
    27// base64传输
    28$encrypted = base64_encode($encrypted);
    29echo $encrypted, "<br/>";
    30
    31//私钥解密
    32openssl_private_decrypt(base64_decode($encrypted), $decrypted, $pi_key);
    33echo $decrypted, "<br/>";
    34
    35// 打印加密明文
    36print_r(json_decode($decrypted, true));
    37

    公钥加密(openssl_public_encrypt),私钥解密(openssl_private_decrypt)。
    私钥加密(openssl_private_encrypt),公钥解密(openssl_public_decrypt)。

    都是一个道理,代码类似。RSA加密解密有个填充方式padding的参数,不同编程语言之间交互,需要注意这个。

    1padding can be one of OPENSSL_PKCS1_PADDING, OPENSSL_SSLV23_PADDING, OPENSSL_PKCS1_OAEP_PADDING,OPENSSL_NO_PADDING

    大于1024字节加密

    值得注意的是,如果选择密钥是1024bit长的(openssl genrsa -out rsa_private_key.pem 1024),那么支持加密的明文长度字节最多只能是1024/8=128byte

    • 如果加密的padding填充方式选择的是OPENSSL_PKCS1_PADDING(这个要占用11个字节),那么明文长度最多只能就是128-11=117字节。如果超出,那么这些openssl加解密函数会返回false

    • 这时有个解决办法,把需要加密的源字符串按少于117个长度分开为几组,在解密的时候以172个字节分为几组。
      其中的『少于117』(只要不大于117即可)和『172』两个数字是怎么来的,值得一说。

    • 为什么少于117就行,因为rsa encrypt后的字节长度是固定的,就是密钥长1024bit/8=128byte。因此只要encrypt不返回false,即只要不大于117个字节,那么返回加密后的都是128byte

    • 172是因为什么?因为128个字节base64_encode后的长度固定是172。

    • 这里顺便普及下base64_encodeencode的长度是和原文长度有个计算公式:
      <br />$len2 = $len1%3 &gt;0 ? (floor($len1/3)4 + 4) : ($len14/3);<br />

    • 明文超出长度的代码(前提是1024bit的密钥长,OPENSSL_PKCS1_PADDING的填充方式,否则数字要变化)

     1<?php
    2$pi_key =  openssl_pkey_get_private($private_key);// 资源类型
    3$pu_key = openssl_pkey_get_public($public_key);
    4
    5$data = array(
    6    'username' => '张三1',
    7    'mobile' => '13321995977',
    8    'info' => '14bMitESqD4PYwODWmy7rrrvyFPEnJJTECLjvKB7IkrVxVDkp1XiJnGKH  
    92h5syHQ5qslPSGYJ1M/XkDnGINwaLVHVD3BoKKgKg1bZn7ao5pXT+herqxaVwWs6  
    10ga63yVSIC8jcODxiuvxJnUMQRLaqoF6aUb/2VWc2T5MDmxLhAkEA3pwGpvXgLiWL  
    113h7QLYZLrLrbFRuRN4CYl4UYaAKokkAvZly04Glle8ycgOc2DzL4eiL4l/+x/gaq  
    12deJU/cHLRQJBANOZY0mEoVkwhU4bScSdnfM6usQowYBEwHYY',
    13);
    14
    15$str = json_encode($data);
    16$en = encrypt_rsa($str, $pu_key);
    17
    18$de = decrypt_rsa($en, $pi_key);
    19echo $de;
    20
    21function encrypt_rsa($data, $pu_key){
    22    $split = str_split($data, 100);// 1024bit && OPENSSL_PKCS1_PADDING  不大于117即可
    23    foreach ($split as $part) {
    24        $isOkay = openssl_public_encrypt($part, $en_data, $pu_key);
    25        if(!$isOkay){
    26            return false;
    27        }
    28        // echo strlen($en_data),'<br/>';
    29        $encode_data .= base64_encode($en_data);
    30    }
    31    return $encode_data;
    32}
    33
    34function decrypt_rsa($data, $pi_key){
    35    $split = str_split($data, 172);// 1024bit  固定172
    36    foreach ($split as $part) {
    37        $isOkay = openssl_private_decrypt(base64_decode($part), $de_data, $pi_key);// base64在这里使用,因为172字节是一组,是encode来的
    38        if(!$isOkay){
    39            return false;
    40        }
    41        $decode_data .= $de_data;
    42    }
    43    return $decode_data;
    44}
    45


  • 相关阅读:
    深度优先搜索初尝试-DFS-LakeCounting POJ No.2386
    hdoj-2053-Switch Game
    《算法竞赛入门经典》习题及反思 -<2>
    高精度N的阶乘-N!
    列举一些有所帮助的blog和文章
    hdoj-2039-三角形
    hdoj-2035-人见人爱a^b
    hdoj-2028-Lowest common multiple plus
    hdoj上的一题和程序设计第二次作业的拓展-人见人爱a+b
    程序设计第三次作业---C++计算器雏形
  • 原文地址:https://www.cnblogs.com/tinywan/p/10179806.html
Copyright © 2011-2022 走看看