什么是RSA?这里粘贴一些定义。
RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。对方收到信息后,用不同的密钥解密并可核对信息摘要。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,截止2017年被普遍认为是最优秀的公钥方案之一。
SET(Secure Electronic Transaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。RSA密钥长度随着保密级别提高,增加很快。下表列出了对同一安全级别所对应的密钥长度。
今天笔者想要分享的是另外一种加密,python中的RSA加密,当我们不用selenium和Chromedriver的时候模拟登录问题常常是我们的一大难关,因为登录的时候可能会遇到一些加单的账号或者密码加密,最常见的也就是md5加密了,sha1加密了,bs64加密了诸如此类,今天笔者想要分享的就是登录的时候数据被加密的时候一种分析解密的情况。
第一步:当我们通过提交过数据表单的时候,通过fiddler抓包发现data这个数据并不是我们所提交的数据,而是一串自己也看不懂的代码,这个时候就需要想到可能是账号或者密码被加密了,需要考虑找到加密函数并破解之,这里笔者分享一个自己遇到的加密问题,如下图:
从上图可知提交的表单数据显然是经过加密过后的,那么如何寻找加密之前的函数呢?这里为大家一一分享过程。
第一种方法:当然是之前笔者所说最简单的方法,通过fiddler来查找,前提是清除cookies使js重新加载一遍,即可找到想要的js文件。
从图片中,我们就可以找到函数到底存在哪一个js文件中。
通过之前笔者分享的:http://www.bm8.com.cn/jsConfusion/ js格式化一下,然后即可找到想要的加密函数。
$.ajax({
type: "POST",
url: $("#ctx").val() + "/login.action",
data: {
userAuthInfo: getUserAuthInfo()
},
success: function (b) {
if (b.promptMsg == null) {
document.cookie = "orgTypeName =" + escape(b.orgTypeName) + ";path=/";
可知需要进一步查找getUserAuthInfo()这个函数,函数如下:
function getUserAuthInfo() {
var d = $("#loginName").val();
var a = $.md5($("#password").val());
var c = $("#validateCode").val();
var g = $("#loginPageType").val();
var e = d + ";" + a + ";" + c + ";" + c + ";" + g;
var b = $.cookies.get("rsaPublicKey");
var f = new JSEncrypt();
f.setPublicKey(b);
return f.encrypt(e)
};
从上中的代码可知 rsaPublicKey 需要这个公钥来加密,显然是rsa加密,那么可以继续查看这个函数。
function getRSAPublicKey() {
$.ajax({
type: "POST",
url: $("#ctx").val() + "/loginRSAPublicKey.action",
success: function (a) {
if (a.rsaPublicKey != null && a.rsaPublicKey != "") {
document.cookie = "rsaPublicKey =" + escape(a.rsaPublicKey) + ";path=/"
} else {
$("#validate_img").click();
$("#tip").text("业务服务器异常")
}
},
error: function () {
$("#validate_img").click();
$("#tip").text("业务服务器异常")
}
})
}
既然我们知道了是RSA加密,那么通过getUserAuthInfo()这个函数即可获取我们想要的加密文件,那么分析:
function getUserAuthInfo() {
var d = $("#loginName").val(); // 获取登录账号
var a = $.md5($("#password").val()); // 获取登录的密码经过md5加密
var c = $("#validateCode").val(); // 验证码的值
var g = $("#loginPageType").val(); // loginPageType同样的可通过fiddler查找找到这个值的由来。
var e = d + ";" + a + ";" + c + ";" + c + ";" + g;
var b = $.cookies.get("rsaPublicKey"); // 得到加密的公钥,其中的公钥的查找可以在上一个页面上的cookies中找到,这个就简答多了。这里就不分享查找公钥的过程了。
var f = new JSEncrypt();
f.setPublicKey(b); // rsa进行加密
return f.encrypt(e)
};
既然分析好了过程那么写成python代码如下:
import base64
from hashlib import md5
from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
e = '登录密码' + ";" + password+";" + 验证码+";"+ 验证码+";"+ "%s" % loginPageType
public_key = """-----BEGIN PUBLIC KEY-----
{rsaPublicKey} // 加密所用到的公钥
-----END PUBLIC KEY-----""".format(rsaPublicKey=rsaPublicKey)
rsakey = RSA.importKey(public_key)
cipher = PKCS1_v1_5.new(rsakey)
cipher_text =base64.b64encode(cipher.encrypt(e))
print cipher_text
以上过程为整个加密的获取,当然你也可以通过其他方法解决这类问题,笔者的方法不一定是最好的,随时欢迎讨论。
原创:任何转载需标明作者和来源,违者必究。