zoukankan      html  css  js  c++  java
  • PHP RSA公私钥的理解和示例说明

    1、生成公钥和私钥

    要应用RSA算法,必须先生成公钥和私钥,公钥和私钥的生成可以借助openssl工具。
    也可以用在线生成公私钥。(网站:http://web.chacuo.net/netrsakeypair) 密钥位数:1024位,密钥格式:PKCS#1 示例生成如下:

    公钥的内容:
    1 -----BEGIN PUBLIC KEY-----
    2 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgFeb3f1f9lwrLrqoNpmODMZe7
    3 eO2t1yzfpY32QacYA/NISqkV6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu4
    4 6KBsgo3p6xcxEUPJNABNGU05YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYET
    5 uqkpR4bN5afMZNmGbQIDAQAB
    6 -----END PUBLIC KEY-----

    私钥的内容:
     1 -----BEGIN RSA PRIVATE KEY-----
     2 MIICWwIBAAKBgQCgFeb3f1f9lwrLrqoNpmODMZe7eO2t1yzfpY32QacYA/NISqkV
     3 6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu46KBsgo3p6xcxEUPJNABNGU05
     4 YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYETuqkpR4bN5afMZNmGbQIDAQAB
     5 AoGALTsjACj93ovPpA8cwzCRC192xKR9W1HhvusS+lJAePucwH8/2Q4dbPV7juKD
     6 SwpRCeZwmIv2MvPT+5jnjvUZylkwMbLHwlb5UcB7cYr/vtZvPz2O2ZNU3jiw7Z9U
     7 Ue/27c3EnIHeIb5PBf9SwTlq1iA79nf5Qb50ontDemf2pY0CQQCse7KkHwOEXk4i
     8 ZnjVCB8J3ir7XBP7VFG/pRuGsr5y99hhEyUd+yznIQgPiDjC3uoIP1gsBbs5LqOV
     9 Sx5ltLHfAkEA7Zlxxa5lPHWGqXFb1fbtq5Ou/228f/qmuMqpXf8BlUAzQ8SFjC3t
    10 jwnL83zMWxgjaqSrXmuNeICay+5/eA7JMwJAbjIBKZWe25yccqHhJMkxe05zS2/C
    11 XFm8eKH1ehMMVcs+dJaUqhjk0S1rRvESwn1EK8y8ejOXL6s6W5FIdFYDJQJAbJ4h
    12 LMW08haoIP35ha8Ep9MzxQFdkwP7A69iDd5t0tUummRUyOiWGTXZTs5Wfa5jQnVV
    13 Ai0Y12WzXlcBXtkjkQJASXjgltdFr/q7gFbZiG6C2/eDz0Ce79dLPShi95uzjYOX
    14 emgrKYbLCyqZXJgWoS9Y/k0kAyZTGHJ9O00JRDH87Q==
    15 -----END RSA PRIVATE KEY-----
    常规:公钥和私钥生成好了之后,私钥自己保存,将公钥交给第三方即可。


    2、php的RSA加密解密

    在做加密解密之前,首先要确保php已经开启了openssl拓展,可以通过phpinfo()函数进行查看。
    通常情况下,有以下两种情形:
    ①通过公钥加密,通过私钥解密;
    ②通过私钥加密,通过公钥解密;
    示例解释:支付宝的业务场景属于第二种情形.
    业务方 向 支付宝 发送支付请求,将sign参数通过自己的私钥加密过后发送到支付宝的接口; (业务方签名sign 属于第二种情形:加密.)
    支付宝 向 业务方 发送支付回调结果,将sign参数通过自己的私钥加密过后发送到业务方的notify接口;(解密支付宝回调sign验签 属于第二种情形:解密 可俗称验签.)
    注:支付宝使用的加密函数是openssl_sign,之后的校验可以使用openssl_verify函数进行校验。

    //公私钥加密示例代码:
     1     $content = '待加密的字符串,自己替换';
     2     //示例直接取私钥内容,自己替换
     3     //注意:priKey是一串连续字符,如果存在空格需要去除
     4     $priKey = 'MIICWwIBAAKBgQCgFeb3f1f9lwrLrqoNpmODMZe7eO2t1yzfpY32QacYA/NISqkV';
     5     $priKey .='6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu46KBsgo3p6xcxEUPJNABNGU05';
     6     $priKey .='YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYETuqkpR4bN5afMZNmGbQIDAQAB';
     7     $priKey .='AoGALTsjACj93ovPpA8cwzCRC192xKR9W1HhvusS+lJAePucwH8/2Q4dbPV7juKD';
     8     $priKey .='SwpRCeZwmIv2MvPT+5jnjvUZylkwMbLHwlb5UcB7cYr/vtZvPz2O2ZNU3jiw7Z9U';
     9     $priKey .='Ue/27c3EnIHeIb5PBf9SwTlq1iA79nf5Qb50ontDemf2pY0CQQCse7KkHwOEXk4i';
    10     $priKey .='ZnjVCB8J3ir7XBP7VFG/pRuGsr5y99hhEyUd+yznIQgPiDjC3uoIP1gsBbs5LqOV';
    11     $priKey .='Sx5ltLHfAkEA7Zlxxa5lPHWGqXFb1fbtq5Ou/228f/qmuMqpXf8BlUAzQ8SFjC3t';
    12     $priKey .='jwnL83zMWxgjaqSrXmuNeICay+5/eA7JMwJAbjIBKZWe25yccqHhJMkxe05zS2/C';
    13     $priKey .='XFm8eKH1ehMMVcs+dJaUqhjk0S1rRvESwn1EK8y8ejOXL6s6W5FIdFYDJQJAbJ4h';
    14     $priKey .='LMW08haoIP35ha8Ep9MzxQFdkwP7A69iDd5t0tUummRUyOiWGTXZTs5Wfa5jQnVV';
    15     $priKey .='Ai0Y12WzXlcBXtkjkQJASXjgltdFr/q7gFbZiG6C2/eDz0Ce79dLPShi95uzjYOX';
    16     $priKey .='emgrKYbLCyqZXJgWoS9Y/k0kAyZTGHJ9O00JRDH87Q==';
    17 
    18     echo createSign($content,$priKey);
    19 
    20     /**
    21      * 创建RSA加密签名
    22      * @param string $content
    23      * @param string $priKey
    24      * @return mixed
    25      */
    26     function createSign($content, $priKey){
    27         //转换成PrivateKey格式
    28         $priKey = convertPrivateKey($priKey);
    29         //获取私钥内容
    30         $openssl_private_key =  openssl_get_privatekey($priKey);
    31         //对数据进行PKCS1签名   签名还有MD5,SHA,RMD根据自己实例代码修改
    32         //openssl_sign($content, $signature, $openssl_private_key, OPENSSL_ALGO_MD5);
    33         @openssl_private_encrypt($content, $signature, $openssl_private_key, OPENSSL_PKCS1_PADDING);
    34         //释放资源
    35         @openssl_free_key($openssl_private_key);
    36         //对签名进行Base64编码,变为可读的字符串
    37         $sign = base64_encode($signature);
    38         if (empty($sign)) {
    39             return false;
    40         }
    41         return $sign;
    42     }
    43 
    44     /**
    45      * 转换PrivateKey
    46      * @param string $priKey
    47      * @return string
    48      */
    49     function convertPrivateKey($priKey) {
    50         //判断是否传入私钥内容
    51         $private_key_string = !empty($priKey) ? $priKey : '';
    52         //64位换行私钥内容
    53         $private_key_string = chunk_split($private_key_string, 64, "
    ");
    54         //私钥头部
    55         $private_key_header = "-----BEGIN RSA PRIVATE KEY-----
    ";
    56         //私钥尾部
    57         $private_key_footer = "-----END RSA PRIVATE KEY-----";
    58         //完整私钥拼接
    59         $private_key_string = $private_key_header.$private_key_string.$private_key_footer;
    60         return $private_key_string;
    61     }
    获取sign签名如下: "TFFHwGlMYgANXiwC+aAu122+K3R0n+Ig5ZfpmqNLEYjeS/EwMSUaYA4V5+aXAklRcSPDyJoERZ2+4sUQP1UGWqcwiKuoiHiZ8Ps1ljrBfQpATHrljyLdrj3yZSa2cOqQArBtCxFB9DGDZsbrsbOl7H/zfl3quKDKoiCwQedaykU="


    //公私钥解密示例代码:
     1       $sign = "TFFHwGlMYgANXiwC+aAu122+K3R0n+Ig5ZfpmqNLEYjeS/EwMSUaYA4V5+aXAklRcSPDyJoERZ2+4sUQP1UGWqcwiKuoiHiZ8Ps1ljrBfQpATHrljyLdrj3yZSa2cOqQArBtCxFB9DGDZsbrsbOl7H/zfl3quKDKoiCwQedaykU=";
     2       //示例直接取公钥内容,自己替换
     3       //注意:publickey,如果存在空格需要去除
     4       $publickey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCgFeb3f1f9lwrLrqoNpmODMZe7';
     5       $publickey .= 'eO2t1yzfpY32QacYA/NISqkV6Y38MmLMqxMdLfEnoSOHyMrwHYQJMTElfTJrPUu4';
     6       $publickey .='6KBsgo3p6xcxEUPJNABNGU05YB7d5Hff/oFL9dDZ+tcsOgUY61UDTG15+C6KUYET';
     7       $publickey .='uqkpR4bN5afMZNmGbQIDAQAB';
     8       echo checkSign($sign,$publickey);
     9 
    10       /**
    11        * RSA解密(验签)
    12        * @param string $sign
    13        * @param string $publickey
    14        * @return 0 or 1
    15        */
    16         function checkSign($sign, $publickey){
    17             //转换成PublicKey格式
    18             $publickey = convertPublicKey($publickey);
    19             //获取公钥钥内容
    20             $openssl_public_key = @openssl_get_publickey($publickey);
    21             //对数据进行解密
    22             //$result = @openssl_verify($content,base64_decode($sign), $openssl_public_key,OPENSSL_ALGO_MD5);
    23             $result = openssl_public_decrypt(base64_decode($sign), $decrypted, $openssl_public_key,OPENSSL_PKCS1_PADDING);
    24             //释放资源
    25             @openssl_free_key($openssl_public_key);
    26             return $result;
    27         }
    28 
    29         /**
    30          * 转换PublicKey
    31          * @param string $publicKey
    32          * @return string
    33          */
    34         function convertPublicKey($publicKey) {
    35             //判断是否传入公钥内容
    36             $public_key_string = !empty($publicKey) ? $publicKey : '';
    37             //64位换行公钥钥内容
    38             $public_key_string = chunk_split($public_key_string, 64, "
    ");
    39             //公钥头部
    40             $public_key_header = "-----BEGIN PUBLIC KEY-----
    ";
    41             //公钥尾部
    42             $public_key_footer = "-----END PUBLIC KEY-----";
    43             //完整公钥拼接
    44             $public_key_string = $public_key_header.$public_key_string.$public_key_footer;
    45             return $public_key_string;
    46         }
    验证返回值是: 1验签成功  0验签失败






  • 相关阅读:
    python 元组及操作
    python 字典所有操作
    python 列表操作
    python 运算符
    python while循环
    python 分支语句 等值判断 逻辑运算符
    GDI+_从Bitmap里得到的Color数组值分解
    服务器设计策略
    服务器设计策略
    IOCP的缓冲区
  • 原文地址:https://www.cnblogs.com/cxx8181602/p/9132946.html
Copyright © 2011-2022 走看看