Skip to content

Instantly share code, notes, and snippets.

@mrts
Last active December 31, 2019 21:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mrts/ccc79fc3c04ef4b8fea7 to your computer and use it in GitHub Desktop.
Save mrts/ccc79fc3c04ef4b8fea7 to your computer and use it in GitHub Desktop.
import hashlib
import subprocess
from M2Crypto import RSA, EVP
MESSAGE='hello'
KEY='key.pem'
PUBKEY='pubkey.pem'
def sign_with_m2_evp():
rsa = EVP.load_key(KEY)
rsa.reset_context(md='sha1')
rsa.sign_init()
rsa.sign_update(MESSAGE)
signature = rsa.sign_final().encode('hex')
return signature
def sign_with_m2_rsa():
sha1_hash = hashlib.sha1(MESSAGE).digest()
rsa = RSA.load_key(KEY)
signature = rsa.private_encrypt(sha1_hash, RSA.pkcs1_padding).encode('hex')
return signature
def sign_with_m2_asn1_rsa():
sha1_hash = hashlib.sha1(MESSAGE).digest()
sha1_asn1_prefix = '3021300906052b0e03021a05000414'.decode('hex')
asn1_hash = sha1_asn1_prefix + sha1_hash
rsa = RSA.load_key(KEY)
signature = rsa.private_encrypt(asn1_hash, RSA.pkcs1_padding).encode('hex')
return signature
def sign_with_openssl():
openssl = subprocess.Popen(('openssl', 'dgst', '-sha1',
'-sign', KEY, '-hex'), stdin=subprocess.PIPE, stdout=subprocess.PIPE)
signature = openssl.communicate(MESSAGE)[0]
return signature.strip()
def verify_with_m2_evp(signature):
key = RSA.load_pub_key(PUBKEY)
rsa = EVP.PKey()
rsa.assign_rsa(key)
rsa.reset_context(md='sha1')
rsa.verify_init()
rsa.verify_update(message)
return rsa.verify_final(signature) == 1
if __name__ == '__main__':
sig1 = sign_with_m2_evp()
sig2 = sign_with_m2_asn1_rsa()
sig3 = sign_with_openssl()
assert sig1 == sig2 == sig3, 'Signatures should be equal'
assert verify_with_m2_evp(sig1), 'Signatures should be valid'
sig4 = sign_with_m2_rsa()
print("With ASN.1 and PKCS#1 padding: " + sig1)
print("Without ASN.1 and PKCS#1 padding: " + sig4)
# Output:
# With ASN.1 and PKCS#1 padding: 2ea07436adf6d7a4ca031410ca6e55f2100321c428c172c7a25cd8944ba30d5969bff9552ddb9441cfd35e9b987cad885d2e6411ded3c07be313ea69f99383177b97e8d599c5a0a6221f384a90d6e6e77048c3b9ce8ec631835c0e1bf685b405179db0c1908285f81102dc41b2c238b163c6bab958e1df440114b564ee90bbe4
# Without ASN.1 and PKCS#1 padding: 2fd4e6a045bb07ef81c8412b29988655f05bb417063891c583764f3572a3cb6f7061e81bb7dfb5d6aa313dae5829ff5785ca54c39baf880c6590944f4502d2ec5d47d414bd4091a5fe4dbde6218a0ff92f0fbf3990eb33575ede7155a0c1216b43a02c1e6a751919b3ac12bb9f993222173c9317fb619d721f7910b7879c6797
# Generate ASN.1:
# SHA-1 OID comes from http://www.oid-info.com/get/1.3.14.3.2.26
#
# $ cat >asn1.conf <<EOF
# asn1 = SEQUENCE:digest_info_and_digest
#
# [digest_info_and_digest]
# dinfo = SEQUENCE:digest_info
# digest = FORMAT:HEX,OCT:`echo MESSAGE | openssl dgst -sha1`
#
# [digest_info]
# algid = OID:1.3.14.3.2.26
# params = NULL
#
# EOF
#
# $ openssl asn1parse -i -genconf asn1.conf -out MESSAGE.dgst.asn1
# Private key:
# -----BEGIN RSA PRIVATE KEY-----
# MIICXgIBAAKBgQDjeFoeg3fDCJXr6uRJ+NSyBAKOFamsc45pA/QUzE1wVcSjomVq
# 6jcAK2LUDCOb4N9p/S8pbmwzQHBHT/qDFcXXGNx3waO6RS65ko09m4aBKr6TfDPm
# RsfwbjuRI35mY8J8M5MllrgJ3d11kuS6h9g2snYvK6/P53x+cFbwnsI0zQIDAQAB
# AoGBALLOHCj4Nt/8k7zK+4CaNLdqJ4gAx0tj2oH6NZdTsVuoT9ZBBW+xhGKBuEHu
# +N7DOVtbRgNPZYY0FQ45dDYum0AqPT2hQ7UHrr/71QO9J4dcZ8ucoEPm/h4om6zO
# LTtet9KnEeZ7ZT2VRivu7ZtWdF1m+LYhcI5L+rR7PKW6axgRAkEA9cUQNJYSENVl
# OSTm4TyLblokiVFDyWdKxFWBxHZ9MGvSdAGJmVqtKLcP7SPv1rgux45fJs97CPZP
# /vY/DBGn6wJBAOzwSV1hghAdGlWbJbglUs1FuQyghSeOnh3alXRUSrL0dlnfqOxk
# DlGgHqj8RfiBjL271qW652HeVcU8CPps4CcCQQDHuO8kbNgdie0KdSyS2WrNsL+E
# P+AAacpepsYf69JsaRLLZvx0/TU+oxV0NwIO0fph/RbiKTXo4JG9tksh+a8lAkEA
# gaDIkpU5QjWZ5cH29fM9hN6jahwcHVMygGTJJZbEM3n5khwCYCoxh0jR3WP/qADA
# jkFJIuzJkErCpCC/TLrqOwJAOu0lu5CbB5aT74f7x9NhHf+jkK9ksw0wEgBi08FU
# QGNnsBLvHGsAZREb3pScNQ8aeUNzyzQaDSh03jAi7L/LIw==
# -----END RSA PRIVATE KEY-----
# Public key:
# -----BEGIN PUBLIC KEY-----
# MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDmwAB/rX0Nu0V6hSLkRAQvoc2J
# ILS3Owzk9L5td72ebMzONxvgIl0BzDpvL0zwpaPLgeIRF4cGTWO2cSKOWe58HOFP
# /rG0boDWkW8ou4wsgHP5uyPfIbvanQPn8UUzPdYYR/P8H/Ch3OTTPzudofpQN9JG
# onON/pyhI/LRTz82qwIDAQAB
# -----END PUBLIC KEY-----
@mrts
Copy link
Author

mrts commented Dec 31, 2019

Verify with a key from cert:

x509_cert = X509.load_cert('certificate.pem')
rsa = x509_cert.get_pubkey().get_rsa()
return rsa.verify(message, signature, algo='sha256') == 1

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