Closed cosven closed 3 years ago
参考文章:
下面这段代码来自上面这篇文章
modulus = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7' nonce = '0CoJUm6Qyw8W8jud' pubKey = '010001' def createSecretKey(size): return (''.join(map(lambda xx: (hex(ord(xx))[2:]), os.urandom(size))))[0:16] def aesEncrypt(text, secKey): pad = 16 - len(text) % 16 text = text + pad * chr(pad) encryptor = AES.new(secKey, 2, '0102030405060708') ciphertext = encryptor.encrypt(text) ciphertext = base64.b64encode(ciphertext) return ciphertext def rsaEncrypt(text, pubKey, modulus): text = text[::-1] rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16) return format(rs, 'x').zfill(256) def encrypted_request(text): text = json.dumps(text) secKey = createSecretKey(16) encText = aesEncrypt(aesEncrypt(text, nonce), secKey) encSecKey = rsaEncrypt(secKey, pubKey, modulus) data = { 'params': encText, 'encSecKey': encSecKey } return data
这段代码最难懂的应该是 rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16) 这句话。所以我就分析分析这句话,以及这些变量的作用。
rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16)
解释一下一些东西: AES 加密算法 是一种对称加密算法。
RSA 加密算法是一种非对称加密算法。
上面的modulus是个16进制的数,这个数由两个质数相乘得到,转换为2进制之后的长度为1024。它的长度代表了RSA加密算法的密钥的长度。目前技术,1024位长度的密钥基本不能被破解。 pubKey应该是一个小于φ(modulus) 的一个随机整数。modulus和pubKey组合起来就是RSA加密的公钥。(所以,这个pubkey变量命名其实不是很妥)
modulus
pubKey
rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16),这段代码的根据是这个公式:m^e ≡ c (mod n)。m 相当于 int(text.encode('hex'), 16), e 相当于 int(pubKey, 16), n 相当于int(modulus, 16),rs 相当于 c,也就是加密后的内容。所以,这句话的意思就是:使用公钥对text进行加密,得到rs。
m^e ≡ c (mod n)
int(text.encode('hex'), 16)
encrypted_request 这个函数比较好理解。 先secKey = createSecretKey(16)随机生成一个密钥。 代码中的 nonce = '0CoJUm6Qyw8W8jud'的 nonce 变量也是一个密钥,是AES加密的密钥。 encText = aesEncrypt(aesEncrypt(text, nonce), secKey)就是先使用nonce作为AES密钥对text加密一次,然后使用随机生成的密钥seckey对加密后的文字再加密一次得到 encText。
encrypted_request
secKey = createSecretKey(16)
nonce = '0CoJUm6Qyw8W8jud'
encText = aesEncrypt(aesEncrypt(text, nonce), secKey)
到这里为止,我再次把所知道的东西列出来:
所以程序对这个 随机生成的密钥 使用 RSA 加密,发给后端,后端就知道了这个随机密钥到底是多少。
基本完了。
问题来了:int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16) 这不就是 RSA 加密算法么,为啥要自己写,难道没有现成的函数么。答案是有的,所以 rsa_encrypt 这个函数可以改写为:
int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16)
rsa_encrypt
from Crypto.PublicKey import RSA def rsa_encrypt(self, text): e = '010001' n = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615'\ 'bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf'\ '695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46'\ 'bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b'\ '8e289dc6935b3ece0462db0a22b8e7' reverse_text = text[::-1] pub_key = RSA.contruct([int(n, 16), int(e, 16)]) encrypt_text = pub_key.encrypt(reverse_text)[0] return encrypt_text
不过,如果当初作者写成这个样子,我也就不去研究 RSA 算法的原理了。(一把泪 =.= )不过也好,学了点数学。
另外,一个有趣的地方: 运算 int(text.encode('hex'), 16) ** int(pubKey, 16) 需要几秒的时间,但是运行这整句代码,却可以秒出结果。(表示不懂啊)
int(text.encode('hex'), 16) ** int(pubKey, 16)
使用 python3 改写之后
def _create_aes_key(self, size): return (''.join([hex(b)[2:] for b in os.urandom(size)]))[0:16] def _aes_encrypt(self, text, key): pad = 16 - len(text) % 16 text = text + pad * chr(pad) encryptor = AES.new(key, 2, '0102030405060708') enc_text = encryptor.encrypt(text) enc_text_encode = base64.b64encode(enc_text) return enc_text_encode def _rsa_encrypt(self, text): e = '010001' n = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615'\ 'bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf'\ '695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46'\ 'bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b'\ '8e289dc6935b3ece0462db0a22b8e7' reverse_text = text[::-1] pub_key = RSA.construct([int(n, 16), int(e, 16)]) encrypt_text = pub_key.encrypt(int(binascii.hexlify(reverse_text), 16), None)[0] return format(encrypt_text, 'x').zfill(256) def encrypt_request(self, data): text = json.dumps(data) first_aes_key = '0CoJUm6Qyw8W8jud' second_aes_key = self._create_aes_key(16) enc_text = self._aes_encrypt( self._aes_encrypt(text, first_aes_key).decode('ascii'), second_aes_key).decode('ascii') enc_aes_key = self._rsa_encrypt(second_aes_key.encode('ascii')) payload = { 'params': enc_text, 'encSecKey': enc_aes_key, } return payload
运算整句快应该是 python 做了优化吧。
https://en.wikipedia.org/wiki/Modular_exponentiation
参考文章:
下面这段代码来自上面这篇文章
这段代码最难懂的应该是
rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16)
这句话。所以我就分析分析这句话,以及这些变量的作用。解释一下一些东西: AES 加密算法 是一种对称加密算法。
RSA 加密算法是一种非对称加密算法。
上面的
modulus
是个16进制的数,这个数由两个质数相乘得到,转换为2进制之后的长度为1024。它的长度代表了RSA加密算法的密钥的长度。目前技术,1024位长度的密钥基本不能被破解。pubKey
应该是一个小于φ(modulus) 的一个随机整数。modulus
和pubKey
组合起来就是RSA加密的公钥。(所以,这个pubkey变量命名其实不是很妥)rs = int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16)
,这段代码的根据是这个公式:m^e ≡ c (mod n)
。m 相当于int(text.encode('hex'), 16)
, e 相当于 int(pubKey, 16), n 相当于int(modulus, 16),rs 相当于 c,也就是加密后的内容。所以,这句话的意思就是:使用公钥对text进行加密,得到rs。encrypted_request
这个函数比较好理解。 先secKey = createSecretKey(16)
随机生成一个密钥。 代码中的nonce = '0CoJUm6Qyw8W8jud'
的 nonce 变量也是一个密钥,是AES加密的密钥。encText = aesEncrypt(aesEncrypt(text, nonce), secKey)
就是先使用nonce作为AES密钥对text加密一次,然后使用随机生成的密钥seckey对加密后的文字再加密一次得到 encText。到这里为止,我再次把所知道的东西列出来:
所以程序对这个 随机生成的密钥 使用 RSA 加密,发给后端,后端就知道了这个随机密钥到底是多少。
基本完了。
问题来了:
int(text.encode('hex'), 16) ** int(pubKey, 16) % int(modulus, 16)
这不就是 RSA 加密算法么,为啥要自己写,难道没有现成的函数么。答案是有的,所以rsa_encrypt
这个函数可以改写为:不过,如果当初作者写成这个样子,我也就不去研究 RSA 算法的原理了。(一把泪 =.= )不过也好,学了点数学。
另外,一个有趣的地方: 运算
int(text.encode('hex'), 16) ** int(pubKey, 16)
需要几秒的时间,但是运行这整句代码,却可以秒出结果。(表示不懂啊)使用 python3 改写之后