8

我是密码学和pycrypto的新手。

我有模数n和私有指数d。根据我在阅读一些文档后的理解,私钥n和组成d

我需要签署一条消息,但我不知道如何使用pycrypto. RSA.construct()方法接受一个元组。但是我必须另外提供e这种方法的公共指数(我没有)。

所以这是我的问题。我是否必须以e某种方式计算才能签署消息?

看来我应该能够通过使用nd(构成私钥)来签署消息。我对么?我可以这样做pycrypto吗?

提前致谢。

4

3 回答 3

4

Actually for decrypting a message encrypted with the public key it's enough to have the private exponent.

That also means you can sign a message, because signing basically is just *de*crypting the plaintext with the private key, which when *en*crypted with the public key will give the plaintext again. Usually you use a hash digest on the plaintext before and sign that...

The reason why you can't decrypt a message uing only n and d with pyrcypto is that it does a blinding step during message decryption, which involves the public exponent, but isn't really needed for the decryption.

But by using some calls to the private API this step can be bypassed.

Therefore this should work:

from Crypto.PublicKey import RSA
from Crypto.Util.number import bytes_to_long, long_to_bytes

full = RSA.generate(2048)

# construct key using only n and d
try:
    # pycrypto >=2.5, only tested with _slowmath
    impl = RSA.RSAImplementation(use_fast_math=False)
    partial = impl.construct((full.n, 0L))
    partial.key.d = full.d
except TypeError:
    # pycrypto <=2.4.1
    partial = RSA.construct((full.n, 0L, full.d))   



pub = full.publickey()

# create message with padding
# http://en.wikipedia.org/wiki/RSA_%28algorithm%29#Padding_schemes
cleartext = ...

signature = partial.sign(cleartext, None)

print "validating message: ", pub.verify(cleartext, signature)


message = pub.encrypt(cleartext, None)

# bypassing the blinding step on decrypt
enc_msg=map(bytes_to_long, message)
dec_msg = map(partial.key._decrypt, enc_msg)

print "decrypting: "
for m in dec_msg:
    print long_to_bytes(m)
于 2012-05-21T18:36:35.883 回答
3

不,你不能ed.

dRSA 在和中是对称的e:您可以很好地互换公钥和私钥的角色。当然,我们专门选择一个保密并透露另一个——但理论上它们做同样的事情。自然,由于您无法从公钥中推断出私钥,因此您也无法从私钥中推断出公钥。

当然,如果您拥有私钥,则意味着生成了密钥对,这意味着您在某处拥有公钥。

于 2012-05-21T17:02:28.930 回答
2

如果您没有公共指数,您可能会猜到它。大多数时候,它不是随机素数,而是静态值。尝试值 65537(十六进制0x010001,费马的第四个数)、3、5、7、13 和 17(按此顺序)。

[编辑] 只需用私钥签名并用公钥验证,看看公钥是否正确。

注意:如果它是随机素数,它与私有指数一样难以找到;这意味着您将尝试破坏 RSA - 对于任何大于 512 位的密钥都不太可能。

于 2012-05-21T18:20:33.553 回答