How can I encrypt a message with my own key using the RSA method?

How can I encrypt a message with my own key using the RSA method?

import rsa
(pubkey, privkey) = rsa.newkeys(512)

message = b'Hello world!'

# шифруем
crypto = rsa.encrypt(message, pubkey)
print(crypto)
Author: 0xdb, 2016-11-12

2 answers

Here is an example using the PyCrypto module:

In [2]: from Crypto.PublicKey import RSA
   ...:
   ...: fn_priv = r'D:\temp\id_rsa'
   ...: fn_pub = r'D:\temp\id_rsa.pub'
   ...:
   ...: with open(fn_pub, 'rb') as pub, open(fn_priv, 'rb') as priv:
   ...:     key_pub = RSA.importKey(pub.read())
   ...:     key_priv = RSA.importKey(priv.read())
   ...:
   ...: encrypted = key_pub.encrypt(b'Hello world!', 111)
   ...:
   ...: decrypted = key_priv.decrypt(encrypted)
   ...:
   ...: print(encrypted)
   ...: print('=' * 60)
   ...: print(decrypted)
   ...:
(b'\xa7\xf1\x8b0\xe8\xcb|\xda\xb9F\\o_\xd5r\x07&\x92/S\x93\xb9\x91\xe9s({\x00\x93U\'\xe6_=M\x07PBI\xab!\xb2 |Fi\xca\xdf\x9d\xb9\x8fJ\x0f\xe6
\xc6\x14\xac\x15?)u\x15\xf6\xb8\xe2\xe8\xef\x8e$1\xe3\xa5v\xa0G<n~\xf0qJ\xd9\xfed\x8a\x15\xbb\xc8\xe0\xfdAiY\xde\xbdm\x8a\xd3x\x81\xea^3Z\xb
0b\x94N\x14\xf4L\x105\x8d\xf85\x98\xc0YC"\x11C\x9b\x97\x04b\xfd]O\xf9e<3\xc1\x82\xb8\xf9\xc3\xb5z\xfd:\x85\x00o*k\x03\x0088\xea\xc2h\xab\xcb
e\xe3\xba\xf8tdM\x96\xc5mD\xc6[\xe3\\\x15\xa28\x03\xe7bff\xaa#u\xa6gV\xc0X\xb7\xd2\xe1\xeb\xd2w\xf6\xe21\x95\x10r\x14=\x15UI\xe9S\x02!\xf9\x
cd\xa4\xd9\x10\xffp\x8fDb\x01Ofd!K0/\xe6\xd5\x16\x13\xf8\x1a^\xd4v"\xea\x89\xe7\x19\xbcu\x89\x11\xfc\x07\x0em7w\xbea\xae\x85\x81\x88Kbh\x8f\
xd6\xad\xca\x88\x9en\xa7\x94\xe9#\x1b4h\xde7k\x925!\x8f=\xf8\xafoa1\x90\xe2h\x10\x8e\xd6\xf4\xde\xc6bL\xaa\x1e\xa6$\xd2w\x8aQc\xecLL\xa7\xb2
\xacD\xe5("\x8c\'\xb8n\xf2uH\x7f\'\xa1\xd8\xf8}0jBNE6y\x871\x95\xa3\xfa\xa9]\xe49\xad/\xbe;*\xdb#\x14\x92\xe4\x1a\r\xb7X\xd7T\xb7\x82>\xa3\x
80y\xec\xf1c\x16\x15&u\x85O\xc5i\xcfCY\x17\x0fq\tI\x9f\x1e\x94_\x81\xb6\x1f\x0f\xc7\xa3\x8bL\xee\xf0_jA\xeea\x15\xa2{ )\xb9\x0c\x96\xaa\xea*
\x8c\xb4g\xd0&\xd1\x9b\x9d\xe3\xe4\xe1d\xa9zi\xe2\x8c\x93\xc8\'V#\xf24tEoXo\xc7\x01\xa2\x92\xb1\x9c\x1a\x0f\x10,\x99r)m\x85F\xcdO\xa3\xe1\x8
b\xc6\xd7\x0e\xc7l\x97u\x94&\x17\xd7\x18\x88\x9c9\xc0\x86\xcf\x1f\xf3yd\xfd=-BF\xdc\xeaj\xf7\xee\xf6$\x8e\xc4\x9c\xb6YCF+\x03\xcb\xe2',)
============================================================
b'Hello world!'

PS for this example, I specifically generated keys without a password, with a length of 4096 bits

 2
Author: MaxU, 2016-11-12 15:25:38

Public key encryption

If Alice wants to send Bob a message encrypted with his public key, without signing the message, then only Bob's public key is needed:

>>> # Generate keys on Bob's computer
>>> import nacl.encoding  # $ pip install pynacl
>>> import nacl.public
>>> skbob = nacl.public.PrivateKey.generate()
>>> skbob.public_key.encode(encoder=nacl.encoding.Base64Encoder)
b'eVNxqEZ1/cbiu8G+aep6OR+ccf2kZLKqDYGhtZPLnRg='

After receiving this key, Alice can encrypt her message to Bob:

>>> # Encrypt message on Alice's computer
>>> import nacl.encoding
>>> import nacl.public
>>> pkbob = nacl.public.PublicKey(b'eVNxqEZ1/cbiu8G+aep6OR+ccf2kZLKqDYGhtZPLnRg=', encoder=nacl.encoding.Base64Encoder)
>>> sealed_box = nacl.public.SealedBox(pkbob)
>>> message = b'hello world'
>>> sealed_box.encrypt(message, encoder=nacl.encoding.Base64Encoder)
b'jhh9bnv5boORCrnEVzKYxh6tMr7iJ9npzLRSpUXGAXXUuFUZQS9Y7UCSBVuyfGvA9suZ4rMDbRfBy0c='

Once Bob receives the encrypted message, it is easy to decrypt it:

>>> # Decrypt message on Bob's computer
>>> encrypted = b'jhh9bnv5boORCrnEVzKYxh6tMr7iJ9npzLRSpUXGAXXUuFUZQS9Y7UCSBVuyfGvA9suZ4rMDbRfBy0c='
>>> unseal_box = nacl.public.SealedBox(skbob)
>>> unseal_box.decrypt(encrypted, encoder=nacl.encoding.Base64Encoder)
b'hello world'

The above code is implemented on Curve25519 primitives on elliptic curves.

Pay attention: the code does not explicitly mention any cryptographic primitive. The fewer moving parts you need to understand, the less likely you are to break something inadvertently. See If You're Typing the Letters A-E-S Into Your Code You're Doing It Wrong.

PyNaCl this is a Python wrapper for the modern libsodium portable crypto library.

RSA encryption

To encrypt the message it is the RSA algorithm, using the public key from the file, you can M2Crypto use the wrapper over OpenSSL:

#!/usr/bin/env python
import base64
from M2Crypto import RSA  # $ pip install m2crypto

# ssh-keygen -f ~/.ssh/id_rsa.pub -e -m PKCS8 >id_rsa.pub.pem
rsa = RSA.load_pub_key('id_rsa.pub.pem')     # load public key
encrypted = rsa.public_encrypt(b'hello world', RSA.pkcs1_oaep_padding)  # encrypt
print(base64.b64encode(encrypted).decode())  # print as base64

Pay attention: this uses the RSAES-OAEP scheme required for new applications.

To decrypt the encrypted_base64 message using the private key from the file:

#!/usr/bin/env python
import base64
import os
from M2Crypto import RSA  # $ pip install m2crypto

rsa = RSA.load_key(os.path.expanduser('~/.ssh/id_rsa'))  # load private key
encrypted = base64.b64decode(encrypted_base64)  # get raw bytes
print(rsa.private_decrypt(encrypted, RSA.pkcs1_oaep_padding).decode())  # decrypt
# -> hello world
 2
Author: jfs, 2018-07-15 09:47:14