RSA加密簡介:
RSA加密算法是最常用的非對稱加密算法,CFCA在證書服務中離不了它。但是有不少新手對它不太了解。下面僅作簡要介紹。RSA是第一個比較完善的公開密鑰算法,它既能用於加密,也能用於數字簽名。RSA以它的三個發明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,這個算法經受住了多年深入的密碼分析,雖然密碼分析者既不能證明也不能否定RSA的安全性,但這恰恰說明該算法有一定的可信性,目前它已經成為最流行的公開密鑰算法。RSA的安全基於大數分解的難度。其公鑰和私鑰是一對大素數(100到200位十進制數或更大)的函數。從一個公鑰和密文恢復出明文的難度,等價於分解兩個大素數之積(這是公認的數學難題)。
特點:
公鑰、私鑰都可以加密,也都可以解密。
1. 加密,其中:用公鑰加密需要私鑰解密,稱為“加密”。由於私鑰是不公開的,確保了內容的保密,沒有私鑰無法獲得內容;
2. 簽名, 用私鑰加密需要公鑰解密,稱為“簽名”。由於公鑰是公開的,任何人都可以解密內容,但只能用發布者的公鑰解密,驗證了內容是該發布者發出的。
3. 公鑰密碼:加密和解密使用不同的密碼的方式,因此公鑰密碼通常也稱為非對稱密碼。
場景:
進行支付、真實信息驗證等安全性需求較高的通信
與其他第三方或合作伙伴進行重要的數據傳輸
問題:
RSA公鑰和私鑰是否可以任意公開一個保密一個,不可以,RSA公鑰和私鑰的位置是不對等的。通過RSA私鑰很容易導出RSA公鑰,但是通過RSA公鑰無法導出RSA私鑰。因為私鑰保存了n,d之外還有q p信息所以能計算出公鑰,但是公鑰只有n,e信息。
所以不要輕易告訴別人私鑰,但是可以告訴別人公鑰。當你告訴別人公鑰,讓人家用公鑰加密,你用私鑰解密,這個過程叫“加密” 知道你的暗號的那個人,可以偷偷傳一句話給你,旁聽者聽不懂,只有你聽得懂。 當你用私鑰加密一個數據,讓別人用公鑰解密,這個過程也就是簽名(你手寫的字才有效)。拿着公鑰的那個人,可以驗證這是你傳來的信息。
問題2:
可以公鑰私鑰是一對多么
答案:1對1
私鑰:握在自己手里,不給別人的。
公鑰:可以交給別人的。
交互過程例子來解釋公鑰私鑰
張三是個有私鑰和公鑰的人,李四沒有,王五沒有。
場景1:
張三將他的公開密鑰傳送給李四。
李四用張三的公開密鑰加密他的消息“我們明天去酒吧喝酒”,然后傳送給李四(一段加密串¥……Q&#Q&^%&^!%&%*]])。
張三用他的私人密鑰解密李四的消息。看明白了,不是亂語,是“我們明天去酒吧喝酒”。
上面的過程叫加密(李四將信息加密傳給張三)
場景2:
張三現在用私鑰加密一句話 “明晚8:00准時到” 傳給李四
李四收到了,用公鑰解密
這個過程叫簽名(張三簽名是自己發出的,不是被人冒充的)
場景3:
張三明天給王五這個公鑰,那么王五也可以傳一個信息給張三
王五說“明天晚上來家里打麻將”
張三用私鑰解密 , 王五和我說“明天晚上來家里打麻將”
這個過程也是加密(王五將信息加密傳給張三)
公鑰和私鑰,簡單理解就是:既然是加密,那肯定是不希望別人知道我的消息,所以只能我才能解密,所以可得出:公鑰負責加密,私鑰負責解密;同理,既然是簽名,那肯定是不希望有人冒充我的身份,只有我才能發布這個數字簽名,所以可得出:私鑰負責簽名,公鑰負責驗證。
如何生成私鑰
用openssl這個工具
安裝
apt-get install openssl
生成
openssl genrsa -out rsa_private_key.pem 1024
如何生成公鑰
將原始 RSA 私鑰轉換為 pkcs8 格式
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out private_key.pem
生成 RSA 公鑰
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
php例子,李四用張三的公鑰加密了一句話給張三。
<?php /* */ error_reporting(E_ALL); echo '<meta charset="utf-8">'; // 公鑰 $publicKey = '-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/qtdtnjxoKndOhsfqSNSM8HKV 1WI8MMQvDE1M8IUo+YCtu6hqLprVAIxwhZOHkH0ezY/3pcQM0h7BeeE5RBsg5K6n HfWmUP3F/cs0m32STlAj60WBboIHvxYFn499xWeG37u08P+/HtAi8Pqc/kKJd8nk DsuXmxdaOFmRX0bIrQIDAQAB -----END PUBLIC KEY-----'; // 私鑰 $privateKey = '-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQC/qtdtnjxoKndOhsfqSNSM8HKV1WI8MMQvDE1M8IUo+YCtu6hq LprVAIxwhZOHkH0ezY/3pcQM0h7BeeE5RBsg5K6nHfWmUP3F/cs0m32STlAj60WB boIHvxYFn499xWeG37u08P+/HtAi8Pqc/kKJd8nkDsuXmxdaOFmRX0bIrQIDAQAB AoGAcSPJ8x07D0oyDxqkm/nN7jxph2Tkjh9DT3p1jvtTv3I4sVVa/wLvxtiCDlHr WlTCZxJ073zck6zdFtx5RLKdR/Hw9RpMHcN3FkjmDMjXoR2ZtlucMbCVCyubSOr0 xGjaKUoQtzIVjCubxGOVcC16I2MxN2c4zBL+RmA4yc6tEMECQQDepBI5cEsOQLyx DH7pHAWLT6qt6poxw/IqvUVozh3LSiF7VvNQnVvhNJPwMHmw+nWv83fjyYZeJBHK rDPlv1ypAkEA3GK0ecmpIwW1xnnguve5l8xQz9w5igPzxgpKrKO07vemSz9cHE9J yFW4AjhYaCwo0KlC9xz90vbLV+lbraeqZQJAU67FrtM3UtcgVUfGF+ZRayh5lb8d T+E/j7LueNMoPbXSWeK3t7A9zasOg/QkeVHalFTl1jd0CsRx74TESPGhaQJBALeL 5W+BCsLGYKwamZZd9057tdpIOgu+WurXa3X5KhnUW8VT0a0qQ/L7oTMIJmksThnq voD8vlFTheuDyP0KJRkCQDwzAk61+cTWbfYeOfZpfON2LVV6I1nuLTT8DdDSBCFf yFJNUji+YdAKkSK697Kp8O2JEkWzse0ePPjsQvFmE0Q= -----END RSA PRIVATE KEY-----'; // 待加密的字符串數據 $data = '我們明天去酒吧喝酒'; // 為避免亂碼,我先進行base64 ecode $data = base64_encode($data); // 加密方用公鑰加密 openssl_public_encrypt($data, $encrypted, $publicKey); // 解密方用私鑰鑰解密 openssl_private_decrypt($encrypted, $decrypted, $privateKey); // 進行base64 decode 得到原字符串 $originData = base64_decode($decrypted); print_r( $originData ); ?>