Generate a pair of private and public keys in python - python

I need to generate a pair of private and public keys in Python. I used to generate them on the site mkjwk, but I want to automate this process.
I need to generate keys in a format like the ones highlighted in yellow in the picture.
I tried to use the cryptography library to solve this problem.
I managed to generate a private key in the required format, but I don’t know how to generate a public key.
key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
)
private_key = key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=serialization.NoEncryption(),
)
I would be very grateful for any help with this. This does not have to be done with the cryptography library, if there is a better way.

I guess using pyopenssl should do it for you
https://www.pyopenssl.org/en/stable/api/crypto.html#OpenSSL.crypto.PKey.generate_key
from OpenSSL import crypto
pk = crypto.PKey()
pk.generate_key(crypto.TYPE_RSA, 2048)
print(f"Private key : {crypto.dump_privatekey(crypto.FILETYPE_PEM, pk)}\n")
print(f"Public key : {crypto.dump_publickey(crypto.FILETYPE_PEM, pk)}\n")
Private key : b'-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDngpyqg5dMlaLL\nNv6WruNAmeA9bZWmr62b0GEOqccjaq6aWscPUYAdzV/xoqAQ8JV6v8OS2O54mi7h\naE0ma4MXpajq8GAf8l/EJoHM1/2mo7r/XDVsxyUgBpd0P/8ds4KiN++x4wr4/Kof\nGHd6+aEwVbRb20ha/IjS6500eDSr1Ld1QMoSWHZ9AJSNgRFc2bm+y/7O/Qf/Oel5\nUSuWKHWBvoyqX5d643ltUDwc3a3H/A0bTwHYYM3W7FbeievNjxs9yM2dUMhPHOS+\n4ATlD1rvsVF686z/MiTicIDe0Sd0Svsk6w2y2QZeYql96EPRcwTAHTlBvpIzJpJx\nJlL2554RAgMBAAECggEBAMvP0NzMvIZPteHxqHA/xxE4ZpGtx/HW96AU811VWltz\nsANzp4t01LVn+O9hnElNhEtsR2EgWdES6/LFQCZywBYxYWRz+iwl1Ol6fQs5m7T4\nr8fgBaieKbDoHK3bKV2ci4UEeaDBoQdSaPK3N3isC5vh18aGZkyzxkDp7JwktzoN\nfinMTmuZPuczl2leqnoY6Dlkkj8hElMLqzAK3TAq5eVh+k0mGklF3LwdLBiG9JTa\nPh1IFYv3OqKvBla+HATyY/596otd3mn7I7EJMekWickNsroxO/wCi7SUvtizyB+d\nAY83u7vY5vJM9kNGU3X6/ac+eK/S65Hp7kRyqhhCV4ECgYEA+ekBijL5jTyTh/a2\nlfh0LKnynXYzyhwM4ZRIEjHGHjkkDSUbDiD9K+8DFrz3btc5rBImRVYABh4uBXJC\ntL42r5A4woxwblD4UZ09OJ+nuuE1ahtjWMTxRnIzKCfsfDCxETxBusMcyCxDggm0\nSAvBkLjGgqimN7nR0QqcRFuEU2MCgYEA7SbSqkFy4m8y+7TLPvA8ynrhR6GJ+xCe\nxOWBcbqs7W6e5q1OTPBnV0gXA1gBcu0AfAz3GZAYDeO44fBOFtDOzALjNOkVRM1U\nFEjESyAGbGAp2tfzMc7rN6UOZ7SJ78HNu7WTjTSmFK+wyxdcEIS93GDOjKYbNqwR\nBw056aRrdPsCgYBhpnI7lf98+JaNIhHmN9btPNrYPD+wUZWW72HZ+ij31kwH9t/D\nfZBvgk0qrVvhq6eVXOInZZtMyK4i4qq+BTVJFImZO1cTRABDo7UwUvIvS6CbfWgs\nX4gHhsgGgNMfE8ecfHcSivrMHL+kKDaRkEZqTkkC9PM+AxXBIOw+qaPjEQKBgC+O\nN3R4x2bs0ZZz/MXUOvyHg6FvnVHBVXU6aKi7vG2oXyj229rF4pM4G5VKEpBPQmed\n2fdAU/KFFdAI9j/RA4cZlSJJE0DGw/OFXAeMln0pE3uVDmmQis6PxMG7DGYNwQnB\nMaOBSUSgrp0rRATz+Xa12vWNYaum+YsmddSKahn9AoGBAKKZ1kBir/KQdWv4XcSD\nVni4KTbBj9W6bDHYASPL7NQnBnrwbkEqZu5U4gHTCpJ6KHMLn0pJv9W3PMjBIlDd\n3va9+Ex6KM0+Xuh21I2HAxzqGFW7b60rGnKx8CKqhzggOpyK9FpaxE3u51b+s6sE\nZac7zriIze30/udoDzckVqJM\n-----END PRIVATE KEY-----\n'
Public key : b'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA54KcqoOXTJWiyzb+lq7j\nQJngPW2Vpq+tm9BhDqnHI2qumlrHD1GAHc1f8aKgEPCVer/DktjueJou4WhNJmuD\nF6Wo6vBgH/JfxCaBzNf9pqO6/1w1bMclIAaXdD//HbOCojfvseMK+PyqHxh3evmh\nMFW0W9tIWvyI0uudNHg0q9S3dUDKElh2fQCUjYERXNm5vsv+zv0H/znpeVErlih1\ngb6Mql+XeuN5bVA8HN2tx/wNG08B2GDN1uxW3onrzY8bPcjNnVDITxzkvuAE5Q9a\n77FRevOs/zIk4nCA3tEndEr7JOsNstkGXmKpfehD0XMEwB05Qb6SMyaScSZS9uee\nEQIDAQAB\n-----END PUBLIC KEY-----\n'

Related

Verifying a RS256 signed JWT

I've tried using my public key vs. using the private key, putting a b in front, doing 3 vs. 1 quotes vs. one quote (and many more things I see here on Stackoverflow) and I keep getting the following error:
ValueError: Could not deserialize key data.
Any ideas?
import jwt
secret_key='''MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwE...pTeoOgWZ'''
token = '''eyJraWQiOiI4NkQ4OEtmIiwiNG2Bua1WoKEI8T..._cXnyThWA'''
#public_key = '''iGaLqP6y-SJCCBq5Hv6pGDbG_SQ11MNj...Mb0jcOTmBRZA2QuYw-zHLwQ'''
payload = jwt.decode(token, secret_key, algorithms=['RS256'])
return payload
Try with the complete public key including the begin and end delimiters and use """ or ''' for a multiline string:
import jwt
token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.K71d-kndywmuxJR-SzDqTARcHJBsHezMeRtDwn4S0NMd3ZmW1LKKqoVQv8rMNam4HK6hsSmB0sqIpKfiLFn73HC1j9-fdBafZNy-9eL4cNr1ldwxj5jD6CwPMjT0mOB01liHFPiIfHDabYV2FzFEV8oaX8CxVL7_CLLv2I01NHo"
pubkey = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCcbV4zk01saMn/VzIDN7rOY8D
BTYGnH6fnYB/wTKBHme6MpuOv+4d48ZKDseP8EcTFQmmAmKeKRGJUzSJ9cN2KlND
a4y2gkEsqh8a9U/7492hVWNB6JkSPrdqrkRho9/q9gCcDlTZROY/RDuf3Y1F1riV
tiFvXvfCp75fpLceIQIDAQAB
-----END PUBLIC KEY-----"""
payload = jwt.decode(token, pubkey, algorithms=['RS256'])
print(payload)
Output:
{'sub': '1234567890', 'name': 'John Doe', 'iat': 1516239022}
(no worries about the key, I just created it online just for demonstration purpose)
I figured it out. My public key above wasn't actually a public key. It is a RSA key modulus. I had to use this tutorial to take this RSA key modulus and the exponent to generate a public key. When i did this, then the JWT.decode functionality worked just fine.
Thanks #jps for your help!

Python rsa module troubles

I need to encrypt some data, so I decided to use rsa module. I need to generate public and private keys. I want to send my public keys to some clients. How can I do this?
import rsa
(public_key, private_key) = rsa.newkeys(512)
So I've already generated it, but public_key now is a structure with two fields e and n. how can I transform it into bytes? And back from bytes to such structure?
You can use PyCrypto module
from Crypto.PublicKey import RSA
key = RSA.generate(512)
private_key = key.exportKey(passphrase='', pkcs=8)
public_key = key.publickey().exportKey()
In your case, try using save_pkcs1 method for saving into PEM format.
UPD:
Code sample for encrypt using rsa:
message = b'message'
# Alternative way - message = 'message'.encode('utf-8')
encrypted = rsa.encrypt(message, public_key)
For decrypt:
rsa.decrypt(encrypted, private_key).decode('utf-8')

How use public key with pyOpenSSL for verify a signed message?

I try to use pyOpenSSL for signed a data, I create key pair (private and publique) and certificate.
I'm a beginner with this technology, I use OpenSSl, but if you have suggestions for generate a signed message with private and public key in python, I'm take !
I want to use RSA and DSA algorithm for my tests.
I find m2Crypto, pyCrypto and other. I do not know what is the best for this.
gnupg for python and pyOpenSSl are more recent visibly.
I used function for signed a message with my private key, and I verify the data.
But when I see the function for verify the signature, in parameters I need :
private key, signature, data and digest type.
I do not know where I am wrong in this code, I find some examples, but I do not understand how this can work because the first parameters for the verify function is a X509 object "certificate is a X509 instance corresponding to the private key which generated the signature." and the second is the signature generated with the private key..
This code work perfectly with the private key :
from OpenSSL import crypto
_k = crypto.PKey()
_cert = crypto.X509()
# Create keys
_k.generate_key(crypto.TYPE_RSA, 2048)
# Add argument for create certificate
_cert.gmtime_adj_notBefore(0)
_cert.gmtime_adj_notAfter(0*365*24*60*60) #10 years expiry date
_cert.set_pubkey(_k)
_cert.sign(_k, 'sha256')
# Create key's file
with open("public_key.pem",'w') as f:
f.write(crypto.dump_publickey(crypto.FILETYPE_PEM, _k))
with open("private_key.pem",'w') as f:
f.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, _k))
with open("certificate.pem",'w') as f:
f.write(crypto.dump_certificate(crypto.FILETYPE_PEM, _cert))
#-------------------------------------------------------------------------------
# Open key and load in var
with open("private_key.pem",'r') as f:
priv_key = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read())
with open("public_key.pem",'r') as f:
pub_key = crypto.load_publickey(crypto.FILETYPE_PEM, f.read())
with open("certificate.pem",'r') as f:
cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
# sign message 'hello world' with private key and certificate
sign = crypto.sign(priv_key, "hello world", 'sha256')
print crypto.verify(cert, sign, "hello world", 'sha256')
So, my question is, how use the public key for verify the data ?
If Bob give a public key to alice, How it checks the message with this public key ?
You have a idea ?
Thanks a lot,
Romain
I found a answer in this post.
from OpenSSL.crypto import load_publickey, FILETYPE_PEM, verify, X509
# ... code ...
x509 = X509()
x509.set_pubkey(pub_key)
# ... code ...
print verify(x509, sign, sha, 'sha256')
I'm wondering.. When I get a message, I use the public key for authenticating the transmitter, but why I have to use the signature to do the verification ? To generate the signature, I need the private key ..
Is there something I did not understand in the use of the library ?
ok I understood my mistake : Cryptography Digital signatures
source

Python JWT and RSA

I would like to learn about creating JWT using RSA public and private key. I am a beginner to learn securing my services. I am using pyjwt right now. I got something error with my testing, here it is:
SAMPLEKEY:
privatekey = """-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQCkC2AfenNMfrU4oMfMZt9aZGBbFjzBTjV9Yttp0GHeVjIKboTwLkiKNqSKrm2Jralbteii2J9h6BeUBpv3B/Os7M0eNeM8B+5Rzm44vcmkzdtufTuX2utjoz8BFjelXw5og2i67NtxgiSHv2x1KCHbGZG+jpDOgjorxFusKbeGjQIDAQABAoGADbMJfvd543x9Y9JBfTdmFaVmSpUL09TVMLhtvGNzmN635RkfrvMeibRQf2hbq3C+QPNrDxZqEQIR3gHDSpj2Z2tGrE95a5o8+I3NBARkKOz41lMFm2AnXZLsM0ma+8S61j8AtELgFuKZWyi2t9A3Otf1+vayZVS/F8pyof0wD10CQQDXDloBpki887jVXtnIauV3Z1744P/uvVkWZOMTMiNF5Xh8SRPn2mNR80vUAAN5SL7zjGyDQeoYKZMRJaLFGsaPAkEAw0bCyz2aA+aWaTM1iyK4XK9/dNPoztE0lmeaHXvI7d1Zp0ipbLwewt4gRbSL7UpxdRQy0ELep4HoSTLt2dQPIwJBANCtS2c4XHKFKIBa5oaUO4+OjdiAM7gMoeqaAMG6sAF99ljbbGZZQnDd3WGclcJVdXzMcOs4xZeml99WnsgWAD8CQAWIfsKFh1Su9voaIl1D6ZduvZzQ2Frr4KKWYu6M8F+VExJDY9GZ7wE0jBONjx11K4vWu63dBzQV4UAZulWexaMCQQCmfoq0l1JtnYhV3LhEN3E8gwUK/0456An5YKunwO8nPrBsrdt/TQ6ZAUzh7JkmabV3h2KXQ+H0/cvfWBOhYaov-----END RSA PRIVATE KEY-----"""
publickey = """-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCkC2AfenNMfrU4oMfMZt9aZGBbFjzBTjV9Yttp0GHeVjIKboTwLkiKNqSKrm2Jralbteii2J9h6BeUBpv3B/Os7M0eNeM8B+5Rzm44vcmkzdtufTuX2utjoz8BFjelXw5og2i67NtxgiSHv2x1KCHbGZG+jpDOgjorxFusKbeGjQIDAQAB-----END PUBLIC KEY-----"""
Here is my sample code:
#app.route('/token')
def token():
encodedToken = jwt.encode({'userid':'1'}, publickey, algorithm = 'RS256')
print(jwt.decode(encodedToken, privatekey, verify=True, algorithms='RS256'))
return "OKE"
And, I am getting this error when running it:
Is there any solution into this ?
Thanks
Basically you'll want to switch the keys, use the private key for "encoding" (signing) and public for "decoding" (verification).
This issue is reported on GitHub here: https://github.com/jpadilla/pyjwt/issues/81
And marked as "closed".

Parse RSA key pair from string in Python

I'm trying to generate/read a RSA-keypair from the publicKey and the privateKey as a String.
Something like this:
priK = "-----BEGIN RSA PRIVATE KEY-----MIIBOQIBAAJAVJhUS0gLqXLOmVv2xG23oFPwim9+rVxGhLUXqKShQCvB3iRMOHn7/GNJumpwmnglcsNXuqAhN0OxqKGGJdtYdwIDAQABAkBP0VrXnSbDvvuIX+k59Xvo3sp7FDAmSoaO+H9WM9+ht5H/f/geIrSEXSIkFLnzniMwtOJ422GmkDkL1F67HuDhAiEAlNauDiq3RqoXufbauyPEOG9fMS2pvB+auT2XCHJhhKsCIQCRgIo7WIRZYnNpNRWaoppUQK3g+aM8sdeBYpbs2nwDZQIgZXIxrmxFAUAb7d+oVFdbfc/DRSTHhPbRoaKuF87GUwMCIFmzaATsLjO42TPMETSS+BfnBAtFe5hIf3Z5pFgC3h9tAiEAgYjug92fmVvE+CcRSg6at7meSEbK/Kxg7Ar4mlkXMlI=-----END RSA PRIVATE KEY-----"
pubK = "-----BEGIN PUBLIC KEY-----MFswDQYJKoZIhvcNAQEBBQADSgAwRwJAVJhUS0gLqXLOmVv2xG23oFPwim9+rVxGhLUXqKShQCvB3iRMOHn7/GNJumpwmnglcsNXuqAhN0OxqKGGJdtYdwIDAQAB-----END PUBLIC KEY-----"
keyPair = RSA.importKey(priK + pubK)
My error that I'm getting is:
in importKey
if lines[1].startswith(b('Proc-Type:4,ENCRYPTED')):
I don't even know if it's possible like that. I didn't really find information about that.
RSA.importKey(key) imports one key. It cannot import concatenated keys.
If you import a private key, then you can extract a public key from that, because common PKCS#1 and PKCS#8 format have all the necessary information to create public key. So, you don't even need to concatenate the public key to it.
Use:
privateKey = RSA.importKey(priK)
publicKey = privateKey.publickey()

Categories