背景:
我正在尝试在短明文(例如32字节)上应用一系列RSA加密和解密步骤。每个步骤都有一个专用的RSA密钥,例如: G。 2048字节。我正在使用Crypto Python软件包。
我的第一个问题是:
keyAlice = RSA.generate(2048)
print keyAlice.size()
这会打印2047
而不是2048
。我必须提供的数字必须是256的倍数,因此尝试使用2049
作为输入失败。
有人能告诉我为什么size()
方法返回的大小与我输入的大小不同吗?
这种陌生感不会打扰我,但它可能是关于我的主要问题发生了什么的线索:
为了我的目标,发送者(Alice)将应用几个步骤,例如:克。
(我假设所有键的大小都相同。)
接收者(Bob)然后可以应用逆:
任何en / decryption步骤的结果都会产生256个字节(2048位)的str
。
注意:有时候结果会更短,例如: G。 255个字节;正如我发现这意味着在开始时剥离零字节;填充它们解决了这个问题。
如果我将其用作下一步的输入,则可以使用
ValueError: Plaintext too large
。我试图找出这种ValueError
出现在哪种情况下,种类的输入使它发生,但它很少发生(约3%的情况)我发现没有简单的解释(因而没有解决方法)。
我的问题是:
size()
方法会返回2047
2048位密钥? (见上文。)encrypt()
和decrypt()
方法有时有输入2048位的问题(虽然它们在处理它时几乎没有问题)?encrypt(encrypt(x))
永不失败),为什么从不有任何麻烦?以下是我正在使用的一些代码,用于演示问题:
import Crypto.Random
from Crypto.PublicKey import RSA
s = 0.
for i in range(1000):
keyAlice = RSA.generate(2048)
keyBob = RSA.generate(2048)
x = Crypto.Random.get_random_bytes(32)
j = 0
try:
while True:
x, = keyAlice.encrypt(x, 0)
j += 1
x = keyBob.decrypt(x)
j += 1
except ValueError:
s += j
print j, s / (i+1)
答案 0 :(得分:2)
RSA是一种代数密码系统。它适用于数字,而不是字节。加密是通过Enc(m,e,n) := me mod n = c
给出的,其中m
是消息,e
是公共指数,n
是模数,c
是密文。重要的是要注意m < n
必须严格为真。否则,它将无法解密
为了完整起见,解密是Dec(c,d,n) := cd mod n = Enc(c,d,n)
完全相同的操作,其中d
是私有指数。
如果您有两个不同的键,那么您的操作将如下所示:
c1 := Enc(m,e1,n1)
c2 := Dec(c1,d2,n2)
send c2
现在,如果n2 < n1
,那么它可能会导致c1 > n2
,因此无法解密。这并非在所有情况下都会发生,取决于n1
和n2
之间的距离。
如果n2 > n1
,那么&#34;发送&#34;将&#34;工作&#34;,但在接收端,你将颠倒模数的顺序,从而再次运行创建一个大于模数的恢复消息的可能性。它看起来像这样:
r1 := Enc(c2,e2,n2)
r2 := Dec(r1,d1,n1)
return r2
毋庸置疑,您不应该设计依赖于偶然性的协议。
您之后使用的协议称为 encrypt-then-sign 。以下问题和答案提供了关于此问题的知识和链接的良好缓存:Should we sign-then-encrypt, or encrypt-then-sign?
无论您决定什么,都需要使用填充版本的加密和签名生成。在pycrypto中,您应该使用Crypto.Cipher.PKCS1_OAEP
for encryption和Crypto.Signature.PKCS1_PSS
for the digital signature。请记住,已签名的数据必须可在接收方进行验证。这意味着无法使用私钥#34;进行加密,因为接收方无法检查它们针对任何内容加密的数据。
发信人:
c := Enc-OAEP(m,e1,n1) s := Sign-PSS(hash(c),d2,n2)
sendc, s
接收器:
ch := Verify-PSS(s,e2,n2)
if ch == hash(c):
mr := Dec-OAEP(c,d1,n1)
return mr
else:
throw Error
为什么size()方法为2048位密钥返回2047?
这看起来像一个错误,不应该发生在this code中。虽然,这是一个相当小的错误。