1、公开密钥加密

  又称非对称加密,需要一对密钥,一个是私人密钥,另一个则是公开密钥。公钥加密的只能私钥解密,用于加密客户上传数据。私钥加密的数据,公钥可以解密,主要用于数字签名。详细介绍可参见维基百科

  2、RSA加密算法

  RSA加密属于非对称加密。RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。维基百科中对RSA算法的安全性进行说明:RSA加密算法

  “对极大整数做因式分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到目前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。”

  3、python进行RSA加密解密 

#生成rsa密钥
from Crypto.PublicKey import RSA
rsa_obj = RSA.generate(1024)
private_pem = rsa_obj.exportKey() #pem格式输出私钥
public_key = rsa_obj.publickey()
public_pem = public_key.exportKey() #将公钥输出成pem格式
print public_pem

#结果类似下面这样
'''
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8jxUVKHjb0kSYRMObVDv20IyN
A1AQS2+oHGB5LNLV+cdMttldWOZwnbHYZrYa4L/MtQhQR4e5JOZhSQe14j2RAWy+
99uXEa88upt3rpAFOjpRcN9larUPXO4yF/5KXI5eo5H2Src+K6Gu+1D1PW411Rqq
d/Uzw8zfx8q5gaH6HwIDAQAB
-----END PUBLIC KEY-----
'''

from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
#rsa加密,通常对加密结果进行base64编码
def encrypt(public_key, message):
    cipher = Cipher_pkcs1_v1_5.new(public_key)
    cipher_text = base64.b64encode(cipher.encrypt(message))
    return cipher_text


#rsa解密
def decrypt(rsakey, encrypt_text):
    cipher = Cipher_pkcs1_v1_5.new(rsakey)
    return cipher.decrypt(base64.b64decode(encrypt_text), '')

msg = 'hello world'
encrypt_text = encrypt(public_key, msg)
print encrypt_text

'''
goWbZ961d34RdEEgvJJtATAcAxXiY6QFTi7ToSmXQEyEKcHTNLqDdkzt3Iqwkhtfro4xCpLm4g+XqSQRNNN+3uQ9/Fahk6TZmi9eRcte5fU72jwyK6ybOAln8Chl8h14bjIsOAahmp9nuYdEFi7tV4ydNE75KMuAcHGlsJYTNjU=
'''

text = decrypt(rsa_obj, encrypt_text)
print text
'hello world'

 

  4、模拟登录cnblog

  访问登录页面,https://passport.cnblogs.com/user/signin,输入用户名密码,查看登录信息,发现用户名密码被加密了

python rsa加密串加密 python3 rsa加密解密_ci

  看了下源代码,发现如下信息

python rsa加密串加密 python3 rsa加密解密_ci_02

 

  我们发现用户名密码被rsa加密了,没有私钥信息,是无法解密其中的内容。其次还有VerificationToken字段。我们可以对用户名密码进行rsa加密,然后模拟登录。代码如下:

#从登录页获取public key,需要手动进行格式化处理
pub = '\n'.join([
'-----BEGIN PUBLIC KEY-----',
'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp0wHYbg/NOPO3nzMD3dndwS0M',
'ccuMeXCHgVlGOoYyFwLdS24Im2e7YyhB0wrUsyYf0/nhzCzBK8ZC9eCWqd0aHbdg',
'OQT6CuFQBMjbyGYvlVYU2ZP7kG9Ft6YV6oc9ambuO7nPZh+bvXH0zDKfi02prknr',
'ScAKC0XhadTHT3Al0QIDAQAB',
'-----END PUBLIC KEY-----'
])

#导入公钥
public_key = RSA.importKey(pub)

input1 = encrypt(public_key,'****') #用户名
input2 = encrypt(public_key,"****") #密码

#登录的信息是保存在cookies中,需要cookeis验证
#使用requests的session,可以自动帮我们处理cookies
s = requests.Session()
headers = {
# 'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
# 'Accept-Encoding':'gzip, deflate, sdch, br',
# 'Accept-Language':'zh-CN,zh;q=0.8',
# 'Connection':'keep-alive',
'Host':'passport.cnblogs.com',
'Upgrade-Insecure-Requests':1,
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36',
}

#打开登录页
r = s.get('https://passport.cnblogs.com/user/signin', headers=headers)
import re
#获取VerificationToken
token = re.search(r"'VerificationToken': '(.*?)'", r.text)
token = token.group(1)
headers = {
# 'Accept':'application/json, text/javascript, */*; q=0.01',
# 'Accept-Encoding':'gzip, deflate, br',
# 'Accept-Language':'zh-CN,zh;q=0.8',
# 'Connection':'keep-alive',
'Content-Type':'application/json; charset=UTF-8',
'Host':'passport.cnblogs.com',
'Origin':'https://passport.cnblogs.com',
'Referer':'https://passport.cnblogs.com/user/signin',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36',
'VerificationToken': token,
'X-Requested-With':'XMLHttpRequest' #这是必须的
}

data = {'input1':input1, 'input2':input2, "remember": True}
r = s.post('https://passport.cnblogs.com/user/signin', data = json.dumps(data), headers=headers)

headers = {
# 'Accept':'text/plain, */*; q=0.01',
# 'Accept-Encoding':'gzip, deflate, br',
# 'Accept-Language':'zh-CN,zh;q=0.8',
# 'Connection':'keep-alive',
'Host':'home.cnblogs.com',
'Referer':'https://home.cnblogs.com/',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36',
'X-Requested-With':'XMLHttpRequest'
}

#获取当前用户信息,验证是否登录成功
print s.get('https://home.cnblogs.com/user/CurrentUserInfo', headers=headers).text


'''
<h1 id="header_user_left">
        欢迎你,lwli
</h1>
<div id="header_user_right">
        <a href="/u/lilinwei340/"><img class="pfs" src="//pic.cnblogs.com/face/sample_face.gif" alt=""/></a>
        <a href="/u/lilinwei340/">lwli</a>
            · <a href="http://www.cnblogs.com/lilinwei340/">我的博客</a>
        · <a href="//home.cnblogs.com/set/account/">设置</a>
        · <a href="javascript:void;" onclick="return logout();">退出</a>
</div>
'''

 

  可以看到模拟登录成功了。如果仅仅为了模拟登录,不用这么麻烦,可以考虑:

  1、不需要自己去进行RSA加密,直接抓取登录时加密后的用户名和密码。

  2、分析登录成功页面的cookies,将其保存下来,请求时只需把cookies带上。