雜項之python利用pycrypto實現RSA
本節內容
- pycrypto模塊簡介
- RSA的公私鑰生成
- RSA使用公鑰加密數據
- RSA使用私鑰解密密文
- 破解博客園登錄
pycrypto模塊簡介
pycrypto模塊是python中用來處理加密解密等信息安全相關的一個很重要模塊。html
該模塊支持的加密方式:python
-
對稱加密方式:web
- AES
- DES
- ARC4
-
散列值計算:算法
- MD5
- SHA
- HMAC
-
公鑰加密和簽名:json
- RSA
- DSA
基本上常見的關於信息安全類的算法均可以支持,因此,這是一個很強大的模塊。windows
安裝方式:pip install pycrypto
若是在windows上的python3.5中安裝完成以後導入from Crypto import Random模塊失敗,須要找到python35安裝目錄下的Lib\site-packages\Crypto\Random\OSRNG\nt.py文件,將import winrandom修改爲from . import winrandom安全
關於加密方式的瞭解能夠看我這邊博客:加密方式介紹
關於非對稱加密算法(RSA)的使用能夠看我這篇博客:數字簽名和數字證書服務器
RSA的公私鑰生成
from Crypto import Random
from Crypto.PublicKey import RSA
random_generator = Random.new().read
rsa = RSA.generate(1024, random_generator)
private_pem = rsa.exportKey()
with open('master-private.pem', 'wb') as f:
f.write(private_pem)
public_pem = rsa.publickey().exportKey()
with open('master-public.pem', 'wb') as f:
f.write(public_pem)
private_pem = rsa.exportKey()
with open('ghost-private.pem', 'wb') as f:
f.write(private_pem)
public_pem = rsa.publickey().exportKey()
with open('ghost-public.pem', 'wb') as f:
f.write(public_pem)
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC6mwuOxuqYi6mugLGr3OuiHwm/hF4kQX1zd5VhGwxYf4H5+pkO
CES2UjOyLP9Xh6w+DJtRwTGE2xwDd3wMfW2wkHijM/uHkM9Jt+oRGIjy4IiXo+7t
ue/NWBkDiQm1qte0YDKlmkFREwvZ5X2KaCsSx+dyKH4QsovxQ3/RxftdmQIDAQAB
AoGAPA5SNe1G6zlnrsW0aL99Bnw+wuhy8/Av082Uwd/WpVTEHBPO1nlKw/LIuHtK
4nzDrmSYSEOJEF0EMwltXwevGSm1wq2FBhX4T+kz3XUpWfv9O0dlHeNtgxeD1QXL
kOxqU4F2WpdALgvi/rlPDd0aIagoXLi8MXkUH7hQlrJpQUECQQC6rygx3jDQA9Iw
kPUXlokEuLod+Kgoa700S5qpJi7vft675+tMG5SZtr+HQeqGHty0fqc8MIcy1fJm
ZYUrogN9AkEA/+RrrOoTYQbR3ENslTsNsiqQa2aZW5XAv9pEyGJBWu/4HUEEa6G3
FY0Y3ACZR0Xaraya8XAgOo61pWm83GBlTQJBAKH2812Ikzr2BbdDHJExdoEVL8xu
/p3LE6U6bt2QFiqNHPtT9C3cw+k0xyi3RJzGS9+A/uDWjYXKXvr92zMG5hUCQFXR
alccTZF9swX2ysSlgGtfIP4T85ymdXUiI208noR79C8DbhMWsgsVPeASh1VC1Rrn
xzLvkq9wyvSFqKQT5AUCQAxMO7KI1rwIm+ISuDEcwxRJXkdFypD74kOSYRxTqMun
Zdu4ku4t6mVeq5kBv1/S2dtF3TiqMRlxmLmV/fx7KHM=
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6mwuOxuqYi6mugLGr3OuiHwm/
hF4kQX1zd5VhGwxYf4H5+pkOCES2UjOyLP9Xh6w+DJtRwTGE2xwDd3wMfW2wkHij
M/uHkM9Jt+oRGIjy4IiXo+7tue/NWBkDiQm1qte0YDKlmkFREwvZ5X2KaCsSx+dy
KH4QsovxQ3/RxftdmQIDAQAB
-----END PUBLIC KEY-----
RSA使用公私鑰加解密數據
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
import base64
message = 'hello ghost, this is a plian text'
with open('ghost-public.pem',"r") as f:
key = f.read()
rsakey = RSA.importKey(key)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
cipher_text = base64.b64encode(cipher.encrypt(message.encode(encoding="utf-8")))
print(cipher_text)
with open('ghost-private.pem') as f:
key = f.read()
rsakey = RSA.importKey(key)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
text = cipher.decrypt(base64.b64decode(cipher_text), "ERROR")
print(text)
b'meBtYXP35VNjtWXsONDluweXdG98tMHjb5GxBLFJ0GJzo+96wSrHe8SDhNJweDJP6/OdeIQ8jP1HKCK+aC9HA12YMSUUqcixsY5s8QUyTs+fkMjGrlC6I7hPLO4DGQbFXEY0jiqP9ycgmAi5FCsDMcm0oEm8/fVzv7vl9QarSN4='
b'hello ghost, this is a plian text'
破解博客園登錄
通過分析博客園登錄方式爲在用戶填入用戶名和密碼以後,點擊登陸時js將會使用JSEncrypt這個開源組件對用戶輸入的用戶名和密碼進行加密,加密的公鑰在js源碼中查找到了,爲」MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp0wHYbg/NOPO3nzMD3dndwS0MccuMeXCHgVlGOoYyFwLdS24Im2e7YyhB0wrUsyYf0/nhzCzBK8ZC9eCWqd0aHbdgOQT6CuFQBMjbyGYvlVYU2ZP7kG9Ft6YV6oc9ambuO7nPZh+bvXH0zDKfi02prknrScAKC0XhadTHT3Al0QIDAQAB」session
後經查詢資料得知該js組件使用的加密方式爲RSA加密,又獲取到了加密的公鑰,因此,咱們能夠本身模擬JS加密方式將咱們本身的用戶名密碼使用RSA加密以後提交到博客園服務器來實現登陸。app
import re
import json
from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.PublicKey import RSA
import base64
import requests
def js_encrypt(text):
key = """-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp0wHYbg/NOPO3nzMD3dndwS0MccuMeXCHgVlGOoYyFwLdS24Im2e7YyhB0wrUsyYf0/nhzCzBK8ZC9eCWqd0aHbdgOQT6CuFQBMjbyGYvlVYU2ZP7kG9Ft6YV6oc9ambuO7nPZh+bvXH0zDKfi02prknrScAKC0XhadTHT3Al0QIDAQAB -----END PUBLIC KEY-----"""
rsakey = RSA.importKey(key)
cipher = Cipher_pkcs1_v1_5.new(rsakey)
cipher_text = base64.b64encode(cipher.encrypt(text.encode(encoding="utf-8")))
print(cipher_text)
value = cipher_text.decode('utf8')
return value
session = requests.Session()
i1 = session.get('https://passport.cnblogs.com/user/signin')
rep = re.compile("'VerificationToken': '(.*)'")
v = re.search(rep, i1.text)
verification_token = v.group(1)
form_data = {
'input1': js_encrypt('你博客園帳號'),
'input2': js_encrypt('你博客園密碼'),
'remember': False
}
i2 = session.post(url='https://passport.cnblogs.com/user/signin',
data=json.dumps(form_data),
headers={
'Content-Type': 'application/json; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'VerificationToken': verification_token}
)
i3 = session.get(url='https://i.cnblogs.com')
print(i3.text)