神魂顛倒論壇

 取回密碼
 加入會員
搜尋
檢視: 46029|回覆: 0
收起左側

[安全] PHP 版本 RSA 加解密

[複製連結]
發表於 2021-8-18 19:53:59 | 顯示全部樓層 |閱讀模式
爲了資料安全,在傳輸之前我們可能會到特定資料先進行RSA加密後再傳送。RSA 私鑰與公鑰對可以通過工具產生。私鑰為加密方儲存用來加密數據,公鑰給到解密方用來解密。示例中的秘鑰對使用的2048強度。

1629287997616.jpg

RSA是目前最有影響力和最常用的公鑰加密演算法,它能夠抵抗到目前為止已知的絕大多數密碼攻擊,至今未被完全攻破。目前已被ISO推薦為公鑰數據加密標準。

RSA公開密鑰密碼體制 所謂的公開密鑰密碼體制就是使用不同的加密密鑰與解密密鑰,是一種「由已知加密密鑰推導出解密密鑰在計算上是不可行的」密碼體制。

在公開密鑰密碼體制中,加密密鑰(即公開密鑰)PK是公開資訊,而解密密鑰(即秘密密鑰)SK是需要保密的。加密演算法E和解密演算法也都是公開的。雖然解密密鑰SK是由公開密鑰PK決定的,但卻不能根據PK計算出SK。

根據密鑰的使用方法,可以將密碼分為對稱密碼和公鑰密碼

對稱密碼:加密和解密使用同一種密鑰的方式

公鑰密碼:加密和解密使用不同的密碼的方式,因此公鑰密碼通常也稱為非對稱密碼。

RSA演算法實現過程 RSA演算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰,即公鑰,而兩個大素數組合成私鑰。公鑰是可發布的供任何人使用,私鑰則為自己所有,供解密之用。

解密者擁有私鑰,並且將由私鑰計算產生的公鑰發布給加密者。加密都使用公鑰進行加密,並將密文發送到解密者,解密者用私鑰解密將密文解碼為明文。

以甲要把資訊發給乙為例,首先確定角色:甲為加密者,乙為解密者。首先由乙隨機確定一個KEY,稱之為密匙,將這個KEY始終儲存在機器B中而不發出來;然後,由這個 KEY計算出另一個KEY,稱之為公匙。這個公鑰的特性是幾乎不可能通過它自身計算出產生它的私鑰。接下來通過網絡把這個公鑰傳給甲,甲收到公鑰後,利用公鑰對資訊加密,並把密文通過網絡發送到乙,最後乙利用已知的私鑰,就對密文進行解碼了。以上就是RSA演算法的工作流程。

原文網址:https://kknews.cc/code/qokbg6o.html


RSA採用 公鑰、私鑰非對稱加密、解密演算法,『非對稱加密演算法』 !透過公鑰與私鑰的方式能讓資料加密更安全,更有保障!
[PHP] 純文本查看 複制代碼
// 加密前原始資料-信用卡資料

$fullText = '{"card_number":"1234567812345678","expiry_date":"202012","cvc2":"000"}';

// 設定公、私鑰檔名
const PRIVATE_KEY = 'private_1024.key';
const PUBLIC_KEY = 'public_1024.pem';

// 如果你是用第二種方法產生
// const PRIVATE_KEY = 'private_2048.key';
// const PUBLIC_KEY = 'public_2048.crt';

// 如果設定密碼
// const PASSPHRASE = 'my_pasword';


function public_encrypt($plain_text)
{
    $fp = fopen(PUBLIC_KEY, "r");
    $pub_key = fread($fp, 8192);
    fclose($fp);
    $pub_key_res = openssl_get_publickey($pub_key);
    if(!$pub_key_res) {
        throw new Exception('Public Key invalid');
    }
    openssl_public_encrypt($plain_text, $crypt_text, $pub_key_res, OPENSSL_PKCS1_OAEP_PADDING);
    openssl_free_key($pub_key_res);
    return base64_encode($crypt_text); // 加密後的內容為 binary 透過 base64_encode() 轉換為 string 方便傳輸
}

function private_decrypt($encrypted_text)
{
    $fp = fopen(PRIVATE_KEY, "r");
    $priv_key = fread($fp, 8192);
    fclose($fp);
    $private_key_res = openssl_get_privatekey($priv_key);
    // $private_key_res = openssl_get_privatekey($priv_key, PASSPHRASE); // 如果使用密碼
    if(!$private_key_res) {
        throw new Exception('Private Key invalid');
    }

    // 先將密文做 base64_decode() 解釋
    openssl_private_decrypt(base64_decode($encrypted_text), $decrypted, $private_key_res, OPENSSL_PKCS1_OAEP_PADDING);
    openssl_free_key($private_key_res);
    return $decrypted;
}

// 將資料進行加密
$r = public_encrypt($fullText);
var_dump($r);

// 將資料進行解密
$r = private_decrypt($r);
var_dump($r);




也可以參考這裡
https://github.com/xinliangnote/Encrypt/blob/master/PHP/php_rsa_key_2048.php

(PHP 4 >= 4.0.6, PHP 5, PHP 7 適用)


生成公鑰和私鑰


使用OpenSSL就可以,一般Linux和mac有自帶的;windows的可自行安裝;


通過如下命令生成;


[Plain Text] 純文本查看 複制代碼
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非對稱加密內容長度有限制,1024位key的最多隻能加密127位資料,如果加密字串過長請使用2048

第一條命令產生原始 RSA私鑰檔案 rsa_private_key.pem;
第二條命令將原始 RSA私鑰轉換為 pkcs8格式;
第三條產生RSA公鑰 rsa_public_key.pem;



可參考這裡:https://bit.ly/3xVF559


PHP openssl 內建函式說明
官方手冊:openssl_public_encrypt
官方手冊:openssl_private_decrypt
上述兩個函式第四個參數 padding 模式可以指定加、解密使用的演算法
(OPENSSL_PKCS1_PADDING, OPENSSL_SSLV23_PADDING, OPENSSL_PKCS1_OAEP_PADDING, OPENSSL_NO_PADDING)
預設為:OPENSSL_PKCS1_PADDING
目前比較推薦 OPENSSL_PKCS1_OAEP_PADDING






您需要登入後才可以回帖 登入 | 加入會員

本版積分規則

Archiver|手機版|小黑屋|Flash2u論壇

GMT+8, 2024-3-29 03:54 , Processed in 0.128063 second(s), 25 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回覆 回到頂端 返回清單