python RSA Cryptography

by Anish

Posted on Thursday November 15 , 2018


Before you Begin

This sample chapter extracted from the book, Python Cryptograhy.


RSA

RSA stands for Ron Rivest, Adi Shamir, and Leonard Adleman, who first publicly described the algorithm in 1978. A user of RSA creates and publishes the product of two large prime numbers, along with an auxiliary value, as their public key. The private KEY (prime factors) MUST BE KEPT SECRET. Anyone can use the public key to encrypt a message, but with currently published methods, if the public key enough it is virtually impossible to decode the message.

In this artricle we will cover two important python library and perform various RSA functions.

  • PYCA/Cryptography
  • pycrypto

pyca Generate RSA Keys

Generate RSA private/public Key and save in PEM format

from cryptography.hazmat.backends import default_backend  
from cryptography.hazmat.primitives.asymmetric import rsa  
from cryptography.hazmat.primitives import serialization  
  
encryptedpass = "myverystrongpassword"  
  
# Generate an RSA Keys  
private_key = rsa.generate_private_key(  
        public_exponent=65537,  
        key_size=2048,  
        backend=default_backend()  
    )  
  
public_key = private_key.public_key()  
  
# Save the RSA key in PEM format  
with open("/tmp/rsakey.pem", "wb") as f:  
    f.write(private_key.private_bytes(  
        encoding=serialization.Encoding.PEM,  
        format=serialization.PrivateFormat.TraditionalOpenSSL,  
        encryption_algorithm=serialization.BestAvailableEncryption(encryptedpass),  
    )  
    )  
  
# Save the Public key in PEM format  
with open("/tmp/rsapub.pem", "wb") as f:  
    f.write(public_key.public_bytes(  
        encoding=serialization.Encoding.PEM,  
        format=serialization.PublicFormat.SubjectPublicKeyInfo,  
    )  
)

pyca RSA-OAEP encryption/ decryption example

Optimal Asymmetric Encryption Padding is a padding scheme often used together with RSA encryption, standardized in PKCS#1 v2

from cryptography.hazmat.backends import default_backend  
from cryptography.hazmat.primitives.asymmetric import padding  
from cryptography.hazmat.primitives import hashes  
from cryptography.hazmat.primitives.serialization import load_pem_private_key  
from cryptography.hazmat.primitives.serialization import load_pem_public_key  
  
encryptedpass = "myverystrongpassword"  
plaintextMessage = "Hello 8gwifi.org"  
alicePubKey = load_pem_public_key(open('/tmp/alicepub.pem', 'rb').read(),default_backend())  
ciphertext = alicePubKey.encrypt(  
    plaintextMessage,  
    padding.OAEP(  
            mgf=padding.MGF1(algorithm=hashes.SHA256()),  
            algorithm=hashes.SHA256(),  
            label=None  
  )  
)  
alicePrivKey = load_pem_private_key(open('/tmp/alice.pem', 'rb').read(),encryptedpass,default_backend())  
  
d = alicePrivKey.decrypt(  
    ciphertext,  
    padding.OAEP(  
            mgf=padding.MGF1(algorithm=hashes.SHA256()),  
            algorithm=hashes.SHA256(),  
            label=None  
  )  
)  
  
assert plaintextMessage, d 

pyca RSA Sign Verify Example

Valid paddings for signatures are PSS and PKCS1v15. PSS is the recommended choice for any new protocols or applications, PKCS1v15 should only be used to support legacy protocols.

Probabilistic Signature Scheme (PSS) is a cryptographic signature scheme designed by Mihir Bellare and Phillip Rogaway

from cryptography.hazmat.backends import default_backend  
from cryptography.hazmat.primitives.asymmetric import padding  
from cryptography.hazmat.primitives import hashes  
from cryptography.hazmat.primitives.serialization import load_pem_private_key  
from cryptography.hazmat.primitives.serialization import load_pem_public_key  
  
encryptedpass = "myverystrongpassword"  
plaintextMessage = "Hello 8gwifi.org"  
  
alicePrivKey = load_pem_private_key(open('/tmp/alice.pem', 'rb').read(),encryptedpass,default_backend())  
  
sig = alicePrivKey.sign(  
    plaintextMessage,  
    padding.PSS(  
        mgf=padding.MGF1(algorithm=hashes.SHA256()),  
        salt_length=padding.PSS.MAX_LENGTH,  
    ),  
    hashes.SHA256()  
)  
alicePubKey = load_pem_public_key(open('/tmp/alicepub.pem', 'rb').read(),default_backend())  
ciphertext = alicePubKey.verify(  
    sig,  
    plaintextMessage,  
    padding.PSS(  
            mgf=padding.MGF1(algorithm=hashes.SHA256()),  
            salt_length=padding.PSS.MAX_LENGTH,  
    ),  
    hashes.SHA256()  
) 

pycrypto

pycrypto example of generating RSA keys in various format (PEM/DER)

  • RSA key size : 1024,2048,4096

pycrypto Generate RSA Keys and store in PEM format

from Crypto.PublicKey import RSA  
from Crypto.Util import asn1  
from base64 import b64decode  
  
#Export RSA public/private KEY in PEM format  
key = RSA.generate(2048)  
privKey = key.exportKey('PEM')  
pubKey =  key.publickey().exportKey('PEM')  
  
#save PEM key into the file  
with open('/tmp/rsakey.pem', 'w') as file:  
    file.write(privKey)  
  
with open('/tmp/rsapub.pem', 'w') as file:  
    file.write(pubKey)  

pycrypto Generate Encrypted RSA PEM Keys

encryptedpass = "myverystrongpassword"  
key = RSA.generate(2048)  
privKey = key.exportKey(passphrase=encryptedpass)  
pubKey = key.publickey().exportKey()  
print privKey  

pycrypto Generate Encrypted RSA Keys in PKCS8 format

encryptedpass = "myverystrongpassword"  
key = RSA.generate(2048)  
privKey = key.exportKey(passphrase=encryptedpass,pkcs=8)  
pubKey = key.publickey().exportKey()  
print privKey  

pycrypto Generate RSA key and export in DER Format

key = RSA.generate(2048)  
#Export RSA key in DER format  
privKey = key.exportKey('DER')  
pubKey =  key.publickey().exportKey('DER')

pycrypto Generate RSA Keys and Perform Encryption and Decryption

from Crypto.PublicKey import RSA  
from Crypto.Util import asn1  
from base64 import b64decode  
  
#Generate RSA Keys and Perform ENcryption and Decryption  
key = RSA.generate(2048)  
pubKey =  key.publickey()  
plaintextMessage = "Hello 8gwifi.org"  
  
#RSA Encryption Using Public Key  
cipherText = pubKey.encrypt(plaintextMessage,32)  
  
#RSA Decryption Using Private Key  
print key.decrypt(cipherText)

pycrypto Load RSA Keys and Perform Encryption and Decryption

from Crypto.PublicKey import RSA
f = open('/tmp/rsakey.pem', 'rb')  
f1 = open('/tmp/rsapub.pem', 'rb')  
  
key = RSA.importKey(f.read())  
pubKey = RSA.importKey(f1.read())  
  
#RSA Encryption Using Public Key  
cipherText = pubKey.encrypt(plaintextMessage,32)  
  
#RSA Decryption Using Private Key  
print key.decrypt(cipherText)

pycrypto PKCS1_OAEP

RSA encryption protocol according to PKCS#1 OAEP

Load the RSA keys and then performing encryption/decryption using PKCS1_OAEP

from Crypto.PublicKey import RSA  
from Crypto.Cipher import PKCS1_OAEP  
  
plaintextMessage = "Hello 8gwifi.org"  
f = open('/tmp/rsakey.pem', 'rb')  
f1 = open('/tmp/rsapub.pem', 'rb')  
  
key = RSA.importKey(f.read())  
pubKey = RSA.importKey(f1.read())  
  
cipher = PKCS1_OAEP.new(pubKey)  
cipherText = cipher.encrypt(plaintextMessage)  
  
#RSA Decryption Using Private Key  
  
cipher = PKCS1_OAEP.new(key)  
print cipher.decrypt(cipherText)

pycrypto PKCS1_PSS Sign Verify

from Crypto.PublicKey import RSA  
from Crypto.Signature import PKCS1_PSS as PKCS  
from Crypto.Hash import SHA  
  
plaintextMessage = "Hello 8gwifi.org"  
  
f = open('/tmp/rsakey.pem', 'rb')  
f1 = open('/tmp/rsapub.pem', 'rb')  
  
key = RSA.importKey(f.read())  
pubKey = RSA.importKey(f1.read())  
  
#RSA Signature Generation  
h = SHA.new()  
h.update(plaintextMessage)  
signer = PKCS.new(key)  
signature = signer.sign(h)  
  
#At the receiver side, verification can be done like using the public part of the RSA key:  
#RSA Signature Verification  
h = SHA.new()  
h.update(plaintextMessage)  
verifier = PKCS.new(pubKey)  
if verifier.verify(h, signature):  
    print "The signature is authentic."  
else:  
    print "The signature is not authentic."

pycrypto PKCS1_v1_5 Encrypt/Decrypt

A DER exported KEY used to perform encryption and decryption.

from Crypto.PublicKey import RSA  
from Crypto.Cipher import PKCS1_v1_5  
plaintextMessage = "Hello 8gwifi.org"  
  
key = RSA.generate(2048)  
pubkey = RSA.importKey(key.publickey().exportKey('DER'))  
privkey = RSA.importKey(key.exportKey('DER'))  
cipher = PKCS1_v1_5.new(pubkey)  
ciphertext = cipher.encrypt(plaintextMessage)  
  
  
dcipher = PKCS1_v1_5.new(privkey)  
#``sentinel`` a value that resembles a plausable random, invalid  
secret = dcipher.decrypt(ciphertext,"sentinel")  
print secret  
  
### pycrypto PEM Example  
  
key = RSA.generate(2048)  
pubkey = RSA.importKey(key.publickey().exportKey('PEM'))  
privkey = RSA.importKey(key.exportKey('PEM'))  
cipher = PKCS1_v1_5.new(pubkey)  
ciphertext = cipher.encrypt(plaintextMessage)  
  
  
dcipher = PKCS1_v1_5.new(privkey)  
#``sentinel`` a value that resembles a plausable random, invalid  
secret = dcipher.decrypt(ciphertext,"sentinel")  
print secret

Thanku for reading !!! Give a Share for Support

Asking for donation sound bad to me, so i'm raising fund from The Modern Cryptography CookBook for Just $9. Leanpub books Discount coupon first 100 reader. No hurry read the sample chapters here then decide.

Alternatively you can buy My all four Cryptography book Just $10.99


Referefce
  • The Modern Cryptography Book.
  • Python Cryptography
  • Cryptography for JavaScript Developer
  • Go lang Cryptography for developers


python Cryptography Topics
python Cryptography Topics
Topics
For Coffee/ Beer/ Amazon Bill and further development of the project Support by Purchasing, The Modern Cryptography CookBook for Just $9 Coupon Price

Cryptography for Python Developers

Cryptography for JavaScript Developers

Go lang ryptography for Developers

Here