问题
Given a public key exponent and modulus like the following, how can I encrypt a string and send it to a server as text?
publicKey: 10001,
modulus: 'd0eeaf178015d0418170055351711be1e4ed1dbab956603ac04a6e7a0dca1179cf33f90294782e9db4dc24a2b1d1f2717c357f32373fb3d9fd7dce91c40b6602'
I am trying to replicate the functionality provided by the javascript rsa library http://www.ohdave.com/rsa/ in python. In javascript, it looks something like this:
setMaxDigits(67); //sets a max digits for bigInt
var key = new RSAKeyPair('10001', '10001', 'd0eeaf178015d0418170055351711be1e4ed1dbab956603ac04a6e7a0dca1179cf33f90294782e9db4dc24a2b1d1f2717c357f32373fb3d9fd7dce91c40b6602');
var encrypted = encryptedString(key, 'message');
console.log(encrypted); //prints '88d58fec172269e5186592dd20446c594dbeb82c01edad41f841666500c9a530e24a282c6527ec66f4c826719f12478c6535bdc2baef86e4ff26906a26398413'
I imagine there is a way to do this with the PyCrypto library but I couldn't find any examples that use the exponent and modulus.
Edit 1:
Using the solution below, it appears to be working. Since I'm using python 2.7 I modified it to look like this:
from Crypto.PublicKey.RSA import construct
from binascii import unhexlify
from codecs import encode
e = long(10001)
n = int(encode('d0eeaf17801.....5d041817005535171', 'hex'), 16)
key = construct((n, e))
a = key.encrypt('hello', None)
print(a)
('.X?\xdc\x81\xfb\x9b(\x0b\xa1\xc6\xf7\xc0\xa3\xd7}U{Q?\xa6VR\xbdJ\xe9\xc5\x1f\x
f9i+\xb2\xf7\xcc\x8c&_\x9bD\x00\x86}V[z&3\\]_\xde\xed\xdc~\xf2\xe1\xa9^\x96\xc3\
xd5R\xc2*\xcb\xd9\x1d\x88$\x98\xb0\x07\xfaG+>G#\xf7cG\xd8\xa6\xf3y_ 4\x17\x0b\x0
3z\x0cvk7\xf7\xebPyo-\xa1\x81\xf5\x81\xec\x17\x9e\xfe3j\x98\xf2\xd5\x80\x1d\xdd\
xaf\xa4\xc8I\xeeB\xdaP\x85\xa7',)
Now I want to convert this encrypted text to a string to send via a post request. But this doesn't seem to work:
a.decode('utf-8')
回答1:
With PyCrypto, you can use the Crypto.PublicKey.RSA.construct() function. You'll need to convert the modulus to an int
. Here's an example (assuming big-endian):
from Crypto.PublicKey.RSA import construct
e = int('10001', 16)
n = int('d0eeaf...0b6602', 16) #snipped for brevity
pubkey = construct((n, e))
Then you can do the usual things (like encrypt) with the key:
pubkey.encrypt(b'abcde', None)
Edit: Note that your public exponent, 10001, is mostly likely hexadecimal. This would correspond to the common public exponent 65537. I've updated the above to reflect that.
回答2:
I tried an alternative way using Crypto.Cipher.PKCS1_OAEP
motivated by: https://cryptobook.nakov.com/asymmetric-key-ciphers/rsa-encrypt-decrypt-examples and it just worked.
PS: There seems to be something wrong with modulus given, as modulus n must be the product of two large primes, thus should not be an even number. A tiny modification of n has been applied to make the example code runnable.
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import binascii
e = int('10001', 16)
n = int('d0eeaf178015d0418170055351711be1e4ed1dbab956603ac04a6e7a0dca1179cf33f90294782e9db4dc24a2b1d1f2717c357f32373fb3d9fd7dce91c40b6601', 16)
# Construct a `RSAobj` with only ( n, e ), thus with only PublicKey
rsaKey = RSA.construct( ( n, e ) )
pubKey = rsaKey.publickey()
print(f"Public key: (n={hex(pubKey.n)}, e={hex(pubKey.e)})")
# Export if needed
pubKeyPEM = rsaKey.exportKey()
print(pubKeyPEM.decode('ascii'))
# Encrypt message using RSA-OAEP scheme
msg = b'Hello, world.'
encryptor = PKCS1_OAEP.new(pubKey)
encrypted = encryptor.encrypt(msg)
print("Encrypted:", binascii.hexlify(encrypted))
来源:https://stackoverflow.com/questions/40094108/i-have-a-rsa-public-key-exponent-and-modulus-how-can-i-encrypt-a-string-using-p