python代码加密封装_【Python】Python3 实现 JS 中 RSA 加密的 NoPadding 模式

前因后果之哗啦啦废话连篇:

这几天本人在 Python 做某网站登陆的时候,发现其登陆时用户名和密码被加密了

F12 仔细看了一下,发现是调用了一个 js 的 rsa 加密库,页面 dom 中有 rsa 公钥

于是乎,用了 3 分钟刷刷的潇洒的写了个 py 脚本,结果对比后傻眼了。。。

web 页面调用 js 库中的加密方式是 nopadding,也就是说,每次加密的结果都一样

而我的 py 脚本每次都不一样!!至于为什么会不一样,以及 padding 的作用请自行百度

于是乎,百度各种 python 库,也没有合适的解决方法

python 库 Crypto 倒是有一个网友给出了方法,但是安装这个库需要安装 Microsoft Visual C++ Build Tools

滚蛋,强行绑架的感觉,还是自己想办法搞定吧。

于是乎...

爆肝研究 RSA 大法

先分析了两个主要 js 文件,Bigint.js 、Barrett.js ,一脸懵逼,一头雾水,不知道再干嘛,仿佛在造一些轮子。。。暂且放过

主要知道了一个事情:

"填充后数据" = "00" + "数据块类型" + "填充字符串" + "00" + "原始数据"

然后又翻看了 python 的 rsa 库源码,其中有一个函数 _pad_for_encryption() ,很可疑,正是在做上述填充数据的事:

此函数位于 python 的 rsa 库 /pkcs1.py 文件中

def _pad_for_encryption(message, target_length):

r"""Pads the message for encryption, returning the padded message.

:return: 00 02 RANDOM_DATA 00 MESSAGE

>>> block = _pad_for_encryption(b'hello', 16)

>>> len(block)

16

>>> block[0:2]

b'\x00\x02'

>>> block[-6:]

b'\x00hello'

"""

max_msglength = target_length - 11

msglength = len(message)

if msglength > max_msglength:

raise OverflowError('%i bytes needed for message, but there is only'

' space for %i' % (msglength, max_msglength))

# Get random padding

padding = b''

padding_length = target_length - msglength - 3

# We remove 0-bytes, so we'll end up with less padding than we've asked for,

# so keep adding data until we're at the correct length.

while len(padding) < padding_length:

needed_bytes = padding_length - len(padding)

# Always read at least 8 bytes more than we need, and trim off the rest

# after removing the 0-bytes. This increases the chance of getting

# enough bytes, especially when needed_bytes is small

new_padding = os.urandom(needed_bytes + 5)

new_padding = new_padding.replace(b'\x00', b'')

padding = padding + new_padding[:needed_bytes]

assert len(padding) == padding_length

return b''.join([b'\x00\x02',

padding,

b'\x00',

message])

重点看 return 的数据,和上面所述的填充方法完全一致。

既然是 nopadding,那就把填充的值全部设置为\x00,填充方式也选\x00,把上述方法关键位置给改掉

完事,重新运行代码,加密后的数据确实不变了,每次都一样,但是和 web 页面中 js 库的还是不一样

突然想到,去看看这个 js 库的官方文档!!

里面开头就介绍了 padding 的填充方式:

* Plaintext In

* ------------

*

* d5 d4 d3 d2 d1 d0

*

*

* NoPadding

* ---------

*

* 00 00 00 00 00 00 00 00 00 /.../ 00 00 d0 d1 d2 d3 d4 d5

果然有猫腻,这里的实现,是把需要加密的字符串反转,然后其他位全部填充\x00

既然知道了具体的填充方法,那就再改动一下 python 的 rsa 库_pad_for_encryption()函数

果然

加密的结果和 web 中的 js 库加密的结果一样(使用相同的公钥)

最后撤销对 python 的 rsa 库文件修改,导入 rsa 库中的相关函数,封装成自己的函数,直接调用自己函数即可

当然,既然 nopadding 模式的搞定了,也可以搞定其他方式的填充了,但是本人暂时用不到,就没有再继续研究

有兴趣的可以自行研究

至此结束。。

后续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值