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的私鑰需要做第三步。 

*/

/*
也可以用生成公鑰私鑰對的網址,直接點擊生成即可
生成: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)
{
    $pem = chunk_split($public_key,64,"\n");
    $pem = "-----BEGIN PUBLIC KEY-----\n" . $content . "-----END PUBLIC KEY-----\n";
    echo $pem;
}

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


//感覺私鑰公鑰可以傳字符串也可以傳資源類型
/**
* 簽名字符串,私鑰簽名
* @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)) {
        $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);
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章