lxinghua

博客园 首页 新随笔 联系 订阅 管理

一、 js逆向之MD5加密算法

MD5:一种哈希算法。

哈希算法,即hash,又叫散列算法,是一类把任意数据转换为定长(或限制长度)数据的算法统称。

特点:

1. 长度固定:固定生成16进制的32位或者16位的数据;

2. 易计算:开发者很容易理解和做出加密工具;

3. 细微性:一个文件,不管多大,小到几k,大到几G,你只要改变里面某个字符,那么都会导致MD5值改变;

4. 不可逆性:你命名知道密文和加密方式,你却无法反向计算出原密码。

MD5并非不可破解,其中可以通过撞库破解。

其破解原理:

1. 建立一个大型的数据库,把日常的各个语句,通过MD5加密成为密文,不断的积累大量的句子,放在一个庞大的数据库里;

2. 比如一个人拿到了别人的密文,想去查询真实的密码,就需要那这个密文去到提供这个数据库的公司网站去查询。

注: 简单说就是通过收集各类语句的MD5加密密文,并以键值对方式存入数据库中;一旦拿到密文,想知道真实密码时,可通过数据库查询对应键值对,查询对应真密码。

关于MD5加盐:

比如QQ密码是“123456”,1. 得到的MD5是:e10adc3949ba59abbe56e057f20f883e, 2. 一个人截取到这个密文,那么通过撞库肯定统计撞出123456,3. 我们要做的就是加盐,QQ的密码还是123456,然后把QQ密码加上我们特定的字符串才计算MD5,所以密码还是那个密码,但是变成求123456密码 加密987的MD5值,然后再得到MD5,那么这个MD5起码可以确认那个数据不会有。

HTML网页中MD5的使用

<script src="https://cdn.bootcss.com/blueimp-md5/1.1.1/js/md5.js"></script>

""""
md5 算法
"""

import hashlib

url = 'https://baike.baidu.com/item/MD5/212708?fromtitle=MD5%E7%AE%97%E6%B3%95&fromid=174909&fr=aladdin'
rv = hashlib.md5(url.encode("utf-8")).hexdigest()

print(rv)
print(len(rv))

二、对称加密DES/AES

 

 对称加密,就是加密和解密用到的密钥是相同的,这种加密方式速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦。

DES/AES:

DES全称为Data Encryption Standard,即数据加密标准,是一种利用密钥加密的块算法

AS全称为Advanced Encryption Standard,即高级加密标准,又称Rijndate加密法,是美国联邦政府采用的一种区块加密标准。

AES五种加密模式:

1. 电码本模式(Electronic Codebook Book,ECB)

这种模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密;

2. 密码分组连接模式(Cipher Block Chaining,CBC)

这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,在与密钥进行加密;

3. 计算器模式(Counter,CTR)

计算器模式不常见,在CTR模式中,有一个自增的算子,这个算子用密钥加密之后的输出和明文异或的结果得到密文,相当于一次一密。这种加密方式简单快速,安全可靠,而且可以并行加密,但是在计算器不能维持很长的情况下,密钥只能使用一次。

4. 密码反馈模式(Cipher FeedBack,CFB)

这种模式较复杂。

5. 输出反馈模式(Output FeedBack, OFB)

这种模式较复杂。

DES与AES的区别

1. 加密后的密文长度不同:DES加密后的密文长度是8的整数倍;AES加密后的密文长度是16的整数倍;

2. 应用场景不同: 企业级开发使用DES足够安全;如果要求高使用AES;

3. DES和AES切换只需修改DES.XX <==> AES.XX

加密案例

"""
对称加密 aes cbc模式
"""
import json
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad
from Cryptodome.Random import get_random_bytes
from base64 import b64encode

# 明文
data = "my name is friendship!"  # 待加密的内容

# 生成密钥
# key = get_random_bytes(16)   # 随机生成的密钥
key = "1234567812345678".encode("utf-8")

# 加密
cipher = AES.new(key, AES.MODE_CBC) # 采用cbc模式进行加密
cipher_text = cipher.encrypt(pad(data.encode("utf-8"), AES.block_size))

# 获取随机向量
iv = b64encode(cipher.iv).decode('utf-8')
# 加密后的内容
ct = b64encode(cipher_text).decode("utf-8")

result = {"iv": iv, "ct": ct}

with open("input.json", "w", encoding="utf-8") as fp:
    json.dump(result, fp)

解密案例

"""
对称解密
"""
import json
from base64 import b64decode
from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import unpad


with open("input.json", "r", encoding="utf-8") as fp:
    rv = json.load(fp)

iv, ct = rv["iv"], rv["ct"]
iv = b64decode(iv)
ct = b64decode(ct)

# key 密钥
key = "1234567812345678".encode("utf-8")
cipher = AES.new(key, AES.MODE_CBC, iv)

# 解密
text = unpad(cipher.decrypt(ct), AES.block_size)
print(text.decode("utf-8"))

三、非对称加密之RSA

 乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。甲方获取乙方的公钥,然后用它对信息加密,乙方得到加密后的信息,用私钥解密。

RSA:1977年,由Rivest、Shamir和Adleman三位数学家设计的一种算法,可以显示非堆成加密。这种算法用他们三个人的名字命名,加做RSA算法。RS算法一直是最为广为使用的“非对称加密算法”。

RSA通常是先生成一对RSA密钥,其中之一是保密密钥(私钥),由用户保存;另一个为公开密钥(公钥),可对外公开;要加密传输内容时,比如A要给B传输信息,此时A先用B的公钥将内容加密后传输,B收到A传输过来的信息后用自己的私钥解密。

公钥私钥生成案例

from Cryptodome.PublicKey import RSA

key = RSA.generate(2048)
private_key = key.export_key()
file_out = open("private.pem", "wb")
file_out.write(private_key)
file_out.close()

public_key = key.publickey().export_key()
file_out = open("receiver.pem", "wb")
file_out.write(public_key)
file_out.close()

非对称加密案例

"""
非对称加密
"""

from Cryptodome.PublicKey import RSA
from Cryptodome.Random import get_random_bytes
from Cryptodome.Cipher import AES, PKCS1_OAEP

data = "I met aliens in UFO. Here is the map.".encode("utf-8")
file_out = open("encrypted_data.bin", "wb")

recipient_key = RSA.import_key(open("receiver.pem").read())
session_key = get_random_bytes(16)

# Encrypt the session key with the public RSA key
# 用公钥加密会话密钥
cipher_rsa = PKCS1_OAEP.new(recipient_key)
enc_session_key = cipher_rsa.encrypt(session_key)

# Encrypt the data with the AES session key
# 用会话私钥去加密数据
cipher_aes = AES.new(session_key, AES.MODE_EAX)
ciphertext, tag = cipher_aes.encrypt_and_digest(data)
[file_out.write(x) for x in (enc_session_key, cipher_aes.nonce, tag, ciphertext)]
file_out.close()

非对称解密案例

"""
非对称解密
"""

from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import AES, PKCS1_OAEP

file_in = open("encrypted_data.bin", "rb")

private_key = RSA.import_key(open("private.pem").read())

enc_session_key, nonce, tag, ciphertext = \
    [file_in.read(x) for x in (private_key.size_in_bytes(), 16, 16, -1)]
file_in.close()

# Decrypt the session key with the private RSA key
# 用私钥去解密会话私钥
cipher_rsa = PKCS1_OAEP.new(private_key)
session_key = cipher_rsa.decrypt(enc_session_key)

# Decrypt the data with the AES session key
# 用会话私钥去解密数据
cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
data = cipher_aes.decrypt_and_verify(ciphertext, tag)
print(data.decode("utf-8"))

四、自定义加密Pyexecjs

 开发者自定定义的规则

1. js很厉害:能看懂别人js的加密写法;

2. python很厉害:用python去实现这个加密。

执行方法:

1. 通过eval直接执行js代码;

2. 通过compile加载js代码,call调用。

案例

import requests
import time
import math
import execjs

url = "http://webapi.cninfo.com.cn/api/sysapi/p_sysapi1008"

js = """

function missjson(input){  
            var keyStr = "ABCDEFGHIJKLMNOP" + "QRSTUVWXYZabcdef" + "ghijklmnopqrstuv"   + "wxyz0123456789+/" + "=";  
            var output = "";  
            var chr1, chr2, chr3 = "";  
            var enc1, enc2, enc3, enc4 = "";  
            var i = 0;  
            do{  
                chr1 = input.charCodeAt(i++);  
                chr2 = input.charCodeAt(i++);  
                chr3 = input.charCodeAt(i++);  
                enc1 = chr1 >> 2;  
                enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);  
                enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);  
                enc4 = chr3 & 63;  
                if (isNaN(chr2)) {  
                    enc3 = enc4 = 64;  
                } else if (isNaN(chr3)) {  
                    enc4 = 64;  
                }  
                output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2)  
                        + keyStr.charAt(enc3) + keyStr.charAt(enc4);  
                chr1 = chr2 = chr3 = "";  
                enc1 = enc2 = enc3 = enc4 = "";  
            }while (i < input.length);  

            return output;  
        } 

"""
timestamp = str(math.floor(int(time.time() * 1000)/1000))
context = execjs.compile(js)
mcode = context.call("missjson", timestamp)

headers = {
    "cookie": 'routeId=.uc2; Hm_lvt_489bd07e99fbfc5f12cbb4145adb0a9b=1677583101,1679665285,1679925404; JSESSIONID=ED4FE4DDAF19C526D8810E9668B3578B; Hm_lpvt_489bd07e99fbfc5f12cbb4145adb0a9b=1680092566',
    "user-agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36',
    "Referer": 'http://webapi.cninfo.com.cn/',
    "Origin": 'http://webapi.cninfo.com.cn',
    "Host": 'webapi.cninfo.com.cn',
    "mcode": mcode
}

# data = "scode=000001-SZE&sdate=2022-03-29&edate=2023-03-29&ctype=0"
scode = input("请输入需要查询的证券代码:")
sdate = input("请输入需要查询开始日期:")
edate = sdate
datas = {
    "scode": scode,
    "sdate": sdate,
    "edate": edate,
    "ctype": 0
}
response = requests.post(url, headers=headers, data=datas)

print(response.text)

 

posted on 2023-03-28 21:55  興華  阅读(203)  评论(0编辑  收藏  举报