Skip to content

Instantly share code, notes, and snippets.

@vanleantking
Forked from aellerton/0_export_public_key.py
Created April 24, 2025 15:45
Show Gist options
  • Save vanleantking/976c53e02949d294193f39b510d9cd3d to your computer and use it in GitHub Desktop.
Save vanleantking/976c53e02949d294193f39b510d9cd3d to your computer and use it in GitHub Desktop.
Python sign message with private key and verify with public key
#!/usr/bin/env python
"""Extract the public key from the private key and write to a file.
"""
from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
with open("private_key.pem", "r") as src:
private_key = RSA.importKey(src.read())
public_key = private_key.publickey()
with open('public_key.txt', 'w') as out:
out.write(public_key.exportKey().decode('utf-8'))
#!/usr/bin/env python
#from base64 import (b64encode, b64decode)
from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
#message = "I want this stream signed"
message = input("message? ")
digest = SHA256.new()
digest.update(message.encode('utf-8'))
# Load private key previouly generated
with open ("private_key.pem", "r") as myfile:
private_key = RSA.importKey(myfile.read())
# Sign the message
signer = PKCS1_v1_5.new(private_key)
sig = signer.sign(digest)
# sig is bytes object, so convert to hex string.
# (could convert using b64encode or any number of ways)
print("Signature:")
print(sig.hex())
#!/usr/bin/env python
import sys
from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
# message = "I want this stream signed"
message = input('Message? ')
digest = SHA256.new()
digest.update(message.encode('utf-8'))
#sig = 'bedc06f6b6cb0edc5c426ec7bb4aad32fbba4efe239e71804047bc0eca3081475641563250092528521879df93ca22474926ecc4baeec98aaf90dffe465ef384917ecf41fbbc332033561f40f13d130d540f9d95114c3b12f05b90351580860453876d4fa30dd6f94a96a92f9684015ccd806c7a053ebf07861091a35d057201'
sig = input('Signature? ')
sig = bytes.fromhex(sig) # convert string to bytes object
# Load public key (not private key) and verify signature
public_key = RSA.importKey(open("public_key.txt").read())
verifier = PKCS1_v1_5.new(public_key)
verified = verifier.verify(digest, sig)
if verified:
print('Successfully verified message')
else:
print('FAILED')

Demonstrate simple private key signature and public key verify

Sequence

You'll need Python 3 and to pip install -r requirements.txt.

Then, set up private and public keys with:

$ bash generate_key.sh 
Generating RSA private key, 1024 bit long modulus
...++++++
..++++++
e is 65537 (0x10001)

$ python 0_export_public_key.py 
(done)

$ cat public_key.txt 
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDU4d3jauQxxI1TmID8q4ejPlMb
1bqYC3GHqnVyJI+TUi84kasfpu3wUbmEhLXwdlSx+w56X6IP2YRhBaYJ7GnI/D2S
dpYh61khiKNaggkrh7d2Z2I1lrtyw0I1209ruKRevKIkvpNKaAVhCYJnBYPOdgJK
2Hg/BGFYnKljSW5GDwIDAetc
-----END PUBLIC KEY-----

Next, create a signature for an arbitrary input message:

$ python 1_sign.py 
message? Hello there
Signature:
6970bbd7c1a1a140fa...............................

Then validate the signature matches for the given input, using only the public key:

$ python 2_verify.py 
Message? Hello there
Signature? 6970bbd7c1a1a140fa24bd65a658ca.........................
Successfully verified message

Validate that a different message with same signature fails:

$ python 2_verify.py 
Message? Foobar
Signature? 6970bbd7c1a1a140fa24bd65a658ca.........................
FAILED
@vanleantking
Copy link
Author

generate keypair openssl from terminal macos
private key:
_openssl genpkey -algorithm RSA -out prod_vtb_private_key.pem -pkeyopt rsa_keygen_bits:2048_

public key: for only extract public key from the existing private key:
_openssl pkey -in prod_vtb_private_key.pem -pubout -out prod_public_key.pem_

for generate public key with more infomation confirm:
_openssl req -new -x509 -sha256 -key prod_vtb_private_key.pem -out prod_publickey_key.cer_
this command require some information:
Country Name (2 letter code): E.g., US
State or Province Name (full name): E.g., California
Locality Name (eg, city): E.g., San Francisco
Organization Name (eg, company): E.g., My Company Ltd
Organizational Unit Name (eg, section): E.g., IT Department
Common Name (e.g. server FQDN or YOUR name): This is important. Use the domain name (like www.example.com), server name, or identifier the certificate is for. For local testing, localhost is often used.
Email Address: Optional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment