RSA加密(非对称加密总结)

/*签名生成
    (1)生成原始RSA私钥文件rsa_private_key.pem
        openssl genrsa -out rsa_private_key.pem 1024
    (2)将原始的RSA私钥转换为pkcs8模式
        openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
    (3)生成RSA公钥 rsa_public_key.pem
        openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

注:php中使用openssl方法,签名和验签,不需要第三步,Java的私钥需要做第三步(java要求PKCS8格式的私钥,php的话PKCS1格式和PKCS8格式均可。PKCS1格式开头是:BEGIN RSA PRIVATE KEY。而PKCS8格式开头是:BEGIN RSA PRIVATE KEY。这是一个小细节。为了避免语言互通有麻烦,用PKCS8格式即可)。 

*/

/*
也可以用生成公钥私钥对的网址,直接点击生成即可
生成:http://web.chacuo.net/netrsakeypair
检测是否配对:http://tool.chacuo.net/cryptrsakeyvalid
 */

#签名处理,先把空格换行符都去掉,如果是上边网站生成的,则无需处理
/*$pem = chunk_split($public_key,64,"\n");//转换为pem格式的公钥  
$pem = "-----BEGIN PUBLIC KEY-----\n" . $content . "-----END PUBLIC KEY-----\n";*/

/**
 * 格式化公钥
 */
function formatPubKey($public_key)
{
    $public_key = chunk_split($public_key,64,"\n");
    $public_key = "-----BEGIN PUBLIC KEY-----\n" . $public_key . "-----END PUBLIC KEY-----\n";
    echo $public_key;
}

/**
 * 格式化私钥
 */
function formatPriKey($private_key)
{
    $private_key = chunk_split($private_key,64,"\n");
    $private_key = "-----BEGIN PRIVATE KEY-----\n" . $private_key . "-----END PRIVATE KEY-----\n";
    echo $private_key;
}


//感觉私钥公钥可以传字符串也可以传资源类型
/**
* 签名字符串,私钥签名
* @param $prestr 需要签名的字符串
* return 签名结果
*/
function rsaSign($prestr) {
    $public_key= file_get_contents('rsa_private_key.pem');
    $pkeyid = openssl_get_privatekey($public_key);
    //openssl_sign($msg, $sign, $ key, OPENSSL_ALGO_SHA1); 
    openssl_sign($prestr, $sign, $pkeyid);
    openssl_free_key($pkeyid);
    $sign = urlsafe_b64encode($sign);//会有些特殊字符'+','/','='直接拼接到url里面,会被替换或者忽略
    return $sign;
}


//$verify = openssl_verify($prestr, urlsafe_b64decode($sign), $public_key);
/**
* 验证签名,公钥验签
* @param $prestr 需要签名的字符串
* @param $sign 签名结果
* return 签名结果
*/
function rsaVerify($prestr, $sign) {
    $sign = urlsafe_b64decode($sign);
    $public_key= file_get_contents('rsa_public_key.pem');
    $pkeyid = openssl_get_publickey($public_key);
    if ($pkeyid) {
        $verify = openssl_verify($prestr, $sign, $pkeyid);
        openssl_free_key($pkeyid);
    }
    if($verify == 1){
        return true;
    }else{
        return false;
    }
}

/**
 * RSA公钥加密,urlsafe_b64encode
 * @param string $key: 公钥
 * @param string $srcStr: 待加密字符串
 * @return string 密文
 */
function rsaPubSafeEncrypt($key, $srcStr){
    $sign = '';
    $res = openssl_pkey_get_public($key);

    if ($res) {
        openssl_public_encrypt($srcStr, $sign, $res);
        openssl_free_key($res);
        $sign = urlsafe_b64encode($sign);
    }

    return $sign ? $sign : '';
}

/**
 * RSA公钥加密,base64_encode
 * @param string $signStr: 待加密字符串
 * @param string $appPubKey: 公钥
 * @return string 密文
 */
function rsaPubEncrypt($signStr, $appPubKey){
    $encrypt = '';
    $pkeyid = openssl_get_publickey($appPubKey);
    if(openssl_public_encrypt($signStr, $encryptedTemp, $pkeyid)) {
        openssl_free_key($pkeyid);
        $encrypt = base64_encode($encryptedTemp);
    }

    return $encrypt ? $encrypt : '';
}

/**
 * RSA分段公钥加密
 * 如果待加密字符串长度超过117,则需要分段加密
 * @param string $key: 公钥
 * @param string $srcStr: 待加密字符串
 * @return string 密文
 */
function rsaPubSplitEncrypt($key, $srcStr){
    $encrypt = '';
    $pkeyid = openssl_pkey_get_public($key);
    $dataArray = str_split($srcStr, 100);// 100

    if ($pkeyid) {
        foreach ($dataArray as $value) {
            $encryptedTemp = "";
            openssl_public_encrypt($value, $encryptedTemp, $pkeyid);//公钥加密
            $encrypt .= $encryptedTemp;
        }

        openssl_free_key($pkeyid);
        $encrypt = base64_encode($encrypt);
    }

    return $encrypt ? $encrypt : '';
}


/**
 * RSA分段私钥解密
 * @param string $key: 私钥
 * @param string $encryptData: 待解密字符串
 * @return string 明文
 */
function rsaPriSplitDecrypt($key, $encryptData)
{
    $decrypted = '';
    $pi_key = openssl_pkey_get_private($key);

    if($pi_key){
        $data = str_split(base64_decode($encryptData), 128);// 128

        foreach ($data as $chunk){
            $partial = '';
            openssl_private_decrypt($chunk, $partial, $pi_key);
            $decrypted .= $partial;
        }
    }

    return $decrypted ? $decrypted : '';
}

//一行也行openssl_public_decrypt(base64_decode($eccryptData), $decrypted, $publicKey);//公钥解密
/**
 * RSA公钥解密
 * @param string $eccryptData: 待解密字符串
 * @param string $publicKey: 公钥
 * @return string 解密后字符串
 */
function pubDecrypt($eccryptData, $publicKey)
{
    $decrypted = "";
    $decodeStr = base64_decode($eccryptData);//如果是urlsafe_b64decode则这里改下
    openssl_public_decrypt($decodeStr, $decrypted, $publicKey);
    return $decrypted ? $decrypted : '';
}


/**
 * RSA私钥加密,base64_encode
 * @param string $signStr: 待加密字符串
 * @param string $appPriKey: 私钥
 * @return string 密文
 */
function rsaPriEncrypt($signStr, $appPriKey){
    $encrypt = '';
    $pkeyid = openssl_get_privatekey($appPriKey);
    if(openssl_private_encrypt($signStr, $encryptedTemp, $pkeyid)) {
        openssl_free_key($pkeyid);
        $encrypt = base64_encode($encryptedTemp);
    }

    return $encrypt ? $encrypt : '';
}

//一行也行openssl_private_decrypt(base64_decode($eccryptData), $decrypted, $prikey);//私钥解密
/**
 * RSA私钥解密
 * @param string $eccryptData: 待解密字符串
 * @param string $decryptKey: 私钥
 * @return string 解密后字符串
 */
function priDecrypt($eccryptData, $decryptKey)
{
    $decrypted = "";
    $decodeStr = base64_decode($eccryptData);//如果是urlsafe_b64decode则这里改下
    openssl_private_decrypt($decodeStr, $decrypted, $decryptKey);
    return $decrypted ? $decrypted : '';
}

function urlsafe_b64encode($string) {
    $data = base64_encode($string);
    $data = str_replace(array('+','/','='),array('-','_',''),$data);
    return $data;
}

function urlsafe_b64decode($string) {
    $data = str_replace(array('-','_'),array('+','/'),$string);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    return base64_decode($data);
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值