无限期解密消息的函数调用挂起

问题描述 投票:0回答:1

我在从私钥生成公钥并尝试使用PyCryptoDome尝试加密/解密消息时遇到问题。解密似乎无限期地挂起。

注意:显然这不是我真正的私钥

-----BEGIN RSA PRIVATE KEY-----
MIIFJAIBAAKCAQEAzdoCzKqtgJs+n66H89khIqgqg4LxAq56FkU0wP9TgcStI0R8
lswVoAep0bC+2Hs1gwwZJBPH1UHn9NcmYHcxUCboemEZGCdfw+3jBGd7EPJx02Av
0QVSHmKTyOh9e/Cc1z+lyI4042T3Tm2Q6xFQOtunzSKrgViN2zMD2sCar7lBM6Kd
5ckBiHs/etgT+mZAW7QkSNb/jOz3Uuhw4z7vey5YewtekfVpGcdkI/XsyVc7TSqk
iBLd8bNyE0XebAp27yB7/RoUf2yPQ0jrIk4IRk7ecWESSgeDswa28a7Np8OGPGtu
Z2ev4SQOQEbbXFEofIjDcxJZvhvVPiNeVI9WIwIDAQABAoIBAQCRUVIHAbllJjLz
SKMY9Zl6sC4y+mdn3Gi7YZrek/oNJenD3j+ShMgCjOZiug8MuKdyHg9+QUIhvidT
1+TaCWRHXPAvVG4B3lBKLgLEKfkRLm93jlnmVYc/HZmOWItQYokvoVlIJEiALqQw
oKn2B+bg/6eM6bWBCu6f/q3xHP6v0ziM890O4vNK630VgrlRXCKBM/S/2jPVXIOZ
HhYMyXHUcUc56MpkgSAmeEF6HjKzGZP3fOvH7VAlphp/ZVduYrf+eRD0zOOjgK0y
DQvqaVCJS0WlBg3ozNBs7yFYdzpSY3XwuTZ0yrG4+I16ISTbt6W8V4Y1rPXfF7u8
Ssn3KXWpAoIBACkrmiju74AfDIZWGzDFBqCICICzyc1WGGrapCaZdxn0IqCnTB4o
0SABiF0jWV5/CrPPODpqWyqmx/3EoUZ+PRAHyBh50dGheY2V+jQUsjaW45Cs1l0B
EGx6HY6U5eWWhcSmVFtPpC16l9x8UC8DdnIr7lw6Ik0RtfijzZImhVZYQD2G7GEo
M4GyP+VeamVHpni9oNteMxwvZKoufPo/yX8JROVorIOXe2uORzpkYo6rC9w7uoGd
X5a9fTcN+UjO5JY5smXSBBl8HKcOlW1CznR2LH0Tag7OTYo0iv0i9e5aTgwVfHsU
vMagz6Z0kkWp1OW08+PQeFk4xD+grHdP3gcCAQUCggEAFc6DjDTq5MkNYEZRhqaF
mRgUsN8J/9ofetGuaseUv0mB4ehbOApUoohNS1AC8TuHVrBmzwIwocnPWooBBo6t
F0WX5eb4jPnjoWwUJ+vibWnExYfWz1JV+a9A4pnZn5734a5cNjVb977cmyu5aP2D
invceDtOmdXMthNFOqlurMp31F8X62pYxdS9ZWd6IYUvFvsSLb+agM5VmpKfHgoV
V1V4ia7E2bqt481ryvELBxhwYsm8QxUxYW2i2jtrk/YKO8v5w1bXVwxXPOFLoqDl
K+jALcvPvGHnzlGAYQ5Yh1SLzHjBA4x7ZRYehsNuCronCziqijuM021u/WjEkTnb
lwIBAQKCAQAg766HJYxmfz04ROKNamuzoAbNXKFxEa0iSINSFF9H9oIaH3AYIKdM
zgaw6RRLmNVcpcaVIeKIhWzLA7Q4ZP2mbKATlKfa55RxRMgpqigrq+lAikUXNA0j
lORyELfq3tFqHqniphzxLt/jlqaMAsUoIyUWlOg9p8TG6XFBuGqrecz+BYnnU1xn
wcy3fruEOVH6MU18S1wWjFCIJTDIMweY1Dcd7VbPrGK8cdKVHRulVaMWli7OF3+r
ysqScZQ6Px1E+vUeQZzhMBbsC6q9zwuQXon9qSGlcdehw6JkG/fx4dgJqsn8EJcF
TXLrkHUEh92EkMMcpsatxwNmGiOSpks5
-----END RSA PRIVATE KEY-----

以下代码段用于读取私钥,导出公钥,对消息进行加密,然后再次对其进行解密。请注意,公钥已被有意地削弱。

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import Crypto.Util
from base64 import *

def encryptMsg(rsakey, message):
    cipher = PKCS1_OAEP.new(rsakey)
    ct = cipher.encrypt(message)
    return ct

def decryptMsg(rsakey, message):
    cipher = PKCS1_OAEP.new(rsakey)
    pt = cipher.decrypt(message)
    return pt

key = RSA.importKey(open('private.key').read())
testpk = key.publickey()
message = b64encode(encryptMsg(testpk, b"test message"))
print(message)
print(decryptMsg(key, b64decode(message)))

谢谢您的时间。

python rsa pycryptodome
1个回答
0
投票

您正在给PyCryptodome一个私钥,该私钥具有极不相称的质数,因此,此密钥实质上已损坏。您在问题中注意到了这一点,但在这里很重要,因为PyCryptodome似乎对素数的大小进行了假设。

为了安全起见,RSA公钥加密通常要求使用两个素数that are close in magnitude

为了安全起见,整数pq应该随机选择,并且其大小应相似,但长度相差几位数,以使分解更加困难。

您似乎通过将第二个素数设为一位数字值而弱化了键:

$ openssl rsa -in private.key -text -noout | sed '/prime1:/,/prime2:/!d;/prime2:/q'
prime1:
    29:2b:9a:28:ee:ef:80:1f:0c:86:56:1b:30:c5:06:
    a0:88:08:80:b3:c9:cd:56:18:6a:da:a4:26:99:77:
    19:f4:22:a0:a7:4c:1e:28:d1:20:01:88:5d:23:59:
    5e:7f:0a:b3:cf:38:3a:6a:5b:2a:a6:c7:fd:c4:a1:
    46:7e:3d:10:07:c8:18:79:d1:d1:a1:79:8d:95:fa:
    34:14:b2:36:96:e3:90:ac:d6:5d:01:10:6c:7a:1d:
    8e:94:e5:e5:96:85:c4:a6:54:5b:4f:a4:2d:7a:97:
    dc:7c:50:2f:03:76:72:2b:ee:5c:3a:22:4d:11:b5:
    f8:a3:cd:92:26:85:56:58:40:3d:86:ec:61:28:33:
    81:b2:3f:e5:5e:6a:65:47:a6:78:bd:a0:db:5e:33:
    1c:2f:64:aa:2e:7c:fa:3f:c9:7f:09:44:e5:68:ac:
    83:97:7b:6b:8e:47:3a:64:62:8e:ab:0b:dc:3b:ba:
    81:9d:5f:96:bd:7d:37:0d:f9:48:ce:e4:96:39:b2:
    65:d2:04:19:7c:1c:a7:0e:95:6d:42:ce:74:76:2c:
    7d:13:6a:0e:ce:4d:8a:34:8a:fd:22:f5:ee:5a:4e:
    0c:15:7c:7b:14:bc:c6:a0:cf:a6:74:92:45:a9:d4:
    e5:b4:f3:e3:d0:78:59:38:c4:3f:a0:ac:77:4f:de:
    07
prime2: 5 (0x5)

prime1p值)是一个“适当的”大质数,使用617位数字,因此大约大10 ^ 616倍。然后,使用此密钥会触发PyCryptodome处理RSA解密的最坏情况。

解密期间,实现为trying to make a negative number positive by repeatedly adding the second prime number

m1 = pow(cp, self._d % (self._p - 1), self._p)
m2 = pow(cp, self._d % (self._q - 1), self._q)
h = m2 - m1
while h < 0:
    h += self._q

在上面的代码中,_p_q属性是两个质数,_d是私钥指数

因为您给定的私钥正在使用这样的极大不成比例质数的两个质数(1位对616位),所以m2的值是3,而m1是616数字短。因此,尝试将q(5)加到616位数的负整数将需要非常长的时间

它应该只使用模运算;您可以在此处用模运算替换while h < 0: h += self._q循环:

if h < 0:
    h %= self._q

这是Crypto/PublicKey/RSA.py,在def _decrypt(self, cyphertext):中,版本3.9.3中的第162行

通过这种更改,解密几乎又是即时的(PyCryptodome使用GMP进行此类大整数运算。

© www.soinside.com 2019 - 2024. All rights reserved.