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
Related
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'
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!
So I have a credit card looking like smart card with a chip. This card logins on a website after the card is inserted into the card reader.
Now I have to write a program in python which can read the card and login on that website. After research on internet I found out that I need to extract :
Certificate and
Public key (since private key cannot be extracted)
from the card and then use these 2 things to create a HTTPs connection (example here) . So far I am able to extract certificate in pem format. But i cant find a way to extract key in pem format till now. I used PyKCS11 to read the card. Below is my code:
from asn1crypto import pem, x509
from PyKCS11 import *
import binascii
pkcs11 = PyKCS11Lib()
pkcs11.load(r'C:\Windows\System32\XXXX.dll')
print(pkcs11.getSlotList(tokenPresent=False))
slot = pkcs11.getSlotList(tokenPresent=False)[0]
print(pkcs11.getTokenInfo(slot))
session = pkcs11.openSession(0, CKF_SERIAL_SESSION | CKF_RW_SESSION)
session.login('123456')
result = []
result_pem = []
# find public key and print modulus
pubKey = session.findObjects([(CKA_CLASS, CKO_PUBLIC_KEY)])[0]
modulus = session.getAttributeValue(pubKey, [CKA_MODULUS])[0]
print("\nmodulus: {}".format(binascii.hexlify(bytearray(modulus))))
#find certificates
certs = session.findObjects([(CKA_CLASS, CKO_CERTIFICATE)])
for cert in certs:
cka_value, cka_id = session.getAttributeValue(cert, [CKA_VALUE, CKA_ID])
cert_der = bytes(cka_value)
cert = x509.Certificate.load(cert_der)
# Write out a PEM encoded value
cert_pem = pem.armor('CERTIFICATE', cert_der)
result.append(cert)
result_pem.append(cert_pem)
with open('cert.pem','wb') as f:
f.write(cert_pem)
print(result)
So here are my questions:
1. Is my approach right?
If yes, then how to extract public key in pem format?
How this smart card authentication actually works on client side and server side?
Public key extraxction
If you already have exported the certificate, it is probably easier to extract the public key from there, instead of from the smartcard. You can use openssl for that:
openssl x509 -in cert.pem -pubkey -out pubkey.pem -noout
Authentication
What you are trying to achieve is to open a TLS connection with mutual authentication using a client certificate. If you do this, the private key of your client certificate signs parts of the handshake to authenticate itself towards the server.
Extracting the certificate and the public key from the smartcard won't help you here. You need to find a library, which allows you to use your private key straight from your PKCS#11 token.
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')
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".