Python RSA, ECDSA384签名/验证
工作中用到了RSA和ECDSA的签名,整理一下脚本代码,分享给有需要的人。RSA支持多种bit位数, ECDSA暂时只支持ECDSA384。RSA的脚本用的python2,ECDSA用python3写的。RSA#!/usr/bin/pythonfrom cryptography.exceptions import InvalidSignaturefrom cryptograph...
·
工作中用到了RSA和ECDSA的签名,整理一下脚本代码,分享给有需要的人。RSA支持多种bit位数, ECDSA暂时只支持ECDSA384。RSA的脚本用的python2,ECDSA用python3写的。
RSA
#!/usr/bin/python
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import load_pem_private_key, \
load_pem_public_key
import os
import sys
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
import binascii
def gen_rsa_key(bit_nr, pri_key, pub_key):
#Pub key and pri key are generated by openssl.
gen_skey = "openssl genrsa -out {} {}".format(pri_key, bit_nr)
print(gen_skey)
os.system(gen_skey)
gen_pkey = "openssl rsa -in {} -pubout -out {}".format(pri_key, pub_key)
print(gen_pkey)
os.system(gen_pkey)
def rsa_sign(data_file_name, private_key_file_name, signautre_file_name = None, hash_type = "SHA256"):
#Read the raw data
data_file = open(data_file_name, "rb")
data = data_file.read()
data_file.close()
#Read privtate key data
key_file = open(private_key_file_name, "rb")
key_data = key_file.read()
key_file.close()
private_key = load_pem_private_key(
key_data,
password=None,
backend=default_backend()
)
if hash_type == "SHA256":
hash_t = hashes.SHA256()
elif hash_type == "SHA384":
hash_t = hashes.SHA384()
else:
hash_t = hashes.SHA512()
signature = private_key.sign(
data,
padding.PKCS1v15(),
hash_t
)
if signautre_file_name != None:
#Write the signature data
signautre_file = open(signautre_file_name, "wb")
signautre_file.write(signature)
signautre_file.close();
print("Signautre data:")
print(binascii.b2a_hex(signature))
def rsa_verify(data_file_name, signature_bin, public_key_file, is_file = True, hash_type = "SHA256"):
#Read the data file
data_file = open(data_file_name, "rb")
data = data_file.read()
data_file.close()
#Read the signature file
signature_file = open(signature_bin, "rb")
signature = signature_file.read()
signature_file.close()
key_file = open(public_key_file, "rb")
key_data = key_file.read()
key_file.close()
public_key = load_pem_public_key(
key_data,
backend=default_backend()
)
if hash_type == "SHA256":
hash_t = hashes.SHA256()
elif hash_type == "SHA384":
hash_t = hashes.SHA384()
else:
hash_t = hashes.SHA512()
verify_ok = False
try:
public_key.verify(
signature,
data,
padding.PKCS1v15(),
hash_t
)
print("RSA correct signature :)")
except InvalidSignature:
print("Invalid signature! :(")
else:
verify_ok = True
return verify_ok
if __name__ == '__main__':
if len(sys.argv) <= 1:
print("paramter not correct")
exit()
if sys.argv[1] == "gen":
if len(sys.argv) <= 4:
print("my_rsa gen pri_key_file pub_key_file bit_nr")
exit()
pri_key = sys.argv[2]
pub_key = sys.argv[3]
bit_nr = sys.argv[4]
gen_rsa_key(bit_nr, pri_key, pub_key)
if sys.argv[1] == "sign":
if len(sys.argv) <= 3:
print("my_rsa sign data pri_key_file sig_file")
print("or my_rsa sign data pri_key_file")
print("or my_rsa sign data pri_key_file sig_file hash")
exit()
data_file = sys.argv[2]
pri_key_file = sys.argv[3]
if len(sys.argv)== 5:
sig_file = sys.argv[4]
rsa_sign(data_file, pri_key_file, sig_file)
elif len(sys.argv) == 6:
sig_file = sys.argv[4]
hash_type = sys.argv[5]
rsa_sign(data_file, pri_key_file, sig_file, hash_type)
else:
rsa_sign(data_file, pri_key_file)
if sys.argv[1] == "verify":
if len(sys.argv) <= 4:
print("my_rsa verify data sig_file pub_key_file")
exit()
data_file = sys.argv[2]
sig_data = sys.argv[3]
pub_key_file = sys.argv[4]
if len(sys.argv) == 6:
hash_type = sys.argv[5]
rsa_verify(data_file, sig_data, pub_key_file, True, hash_type)
else:
rsa_verify(data_file, sig_data, pub_key_file)
ECDSA384
#!/usr/bin/python3
import os
import sys
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import ec, rsa
from cryptography.hazmat.primitives import hashes
import codecs
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature, encode_dss_signature
from cryptography.x509 import load_pem_x509_certificate
from cryptography.exceptions import InvalidSignature
import binascii
from cryptography.hazmat.primitives.asymmetric import padding
def bit_to_bytes(a):
return (a + 7) // 8
def gen_ecdsa_key(pri_key, cert_file, ecdsa_type = "SECP384"):
#Only support ECDSA384 so far, using openssl
gen_ecdsa_pri_key_cmd = "openssl ecparam -genkey -text -out {} -name secp384r1".format(pri_key)
print(gen_ecdsa_pri_key_cmd)
os.system(gen_ecdsa_pri_key_cmd)
gen_ecdsa_cert_key_cmd = "openssl req -new -verbose -pubkey -inform PEM -key {} -x509 -nodes -days 10" \
" -out {}".format(pri_key, cert_file)
print(gen_ecdsa_cert_key_cmd)
os.system(gen_ecdsa_cert_key_cmd)
#Only support ECDSA384
def ecdsa_sign(data_file_name, pri_key_file_name, sig_file_name):
#Read the raw data
data_file = open(data_file_name, "rb")
data = data_file.read()
data_file.close()
#Read the pri_key_file
pri_key_file = open(pri_key_file_name, "rb")
key_data = pri_key_file.read()
pri_key_file.close()
digest = hashes.Hash(
hashes.SHA384(),
default_backend()
)
digest.update(data)
dgst = digest.finalize()
print("Data digest to sign: {:s}".format(dgst.hex()))
skey = load_pem_private_key(
key_data, password=None, backend=default_backend())
sig_data = skey.sign(
data,
ec.ECDSA(hashes.SHA384())
)
sig_r, sig_s = decode_dss_signature(sig_data)
sig_bytes = b''
key_size_in_bytes = bit_to_bytes(skey.public_key().key_size)
sig_r_bytes = sig_r.to_bytes(key_size_in_bytes, "big")
sig_bytes += sig_r_bytes
print("ECDSA signature R: {:s}".format(sig_r_bytes.hex()))
sig_s_bytes = sig_s.to_bytes(key_size_in_bytes, "big")
sig_bytes += sig_s_bytes
print("ECDSA signature S: {:s}".format(sig_s_bytes.hex()))
print("ECDSA signautre: {:s}".format(sig_bytes.hex()))
#Write sig to sig_file
sig_file = open(sig_file_name, "wb")
sig_file.write(sig_bytes)
sig_file.close()
#Only support ECDSA384
def ecdsa_verify(data_file, sig_data, pub_key_file):
data_f = open(data_file, "rb")
pay_load = data_f.read()
data_f.close()
sig_f = open(sig_data, "rb")
r_s = sig_f.read()
sig_f.close()
with open(pub_key_file, 'rb') as fpkey:
pem_data = fpkey.read()
cert = load_pem_x509_certificate(pem_data, default_backend())
public_key = cert.public_key()
if isinstance(public_key, ec.EllipticCurvePublicKey):
sig_r = int.from_bytes(r_s[:int(len(r_s) / 2)], byteorder='big')
sig_s = int.from_bytes(r_s[-int(len(r_s) / 2):], byteorder='big')
signature = encode_dss_signature(sig_r, sig_s)
try:
public_key.verify(
signature,
pay_load,
ec.ECDSA(hashes.SHA384())
)
print("ECDSA Correct signature detected.. :)\n")
except InvalidSignature:
print("ECDSA Invalid signature detected.. :(\n")
else:
print("RSA not yet supported")
exit()
if __name__ == '__main__':
if len(sys.argv) <= 1:
print("paramter not correct")
exit()
if sys.argv[1] == "gen":
if len(sys.argv) <= 3:
print("my_ecdsa gen pri_key_file pub_key_file")
exit()
pri_key = sys.argv[2]
pub_key = sys.argv[3]
gen_ecdsa_key(pri_key, pub_key)
if sys.argv[1] == "sign":
if len(sys.argv) <= 3:
print("my_ecdsa sign data pri_key_file sig_file")
print("or my_rsa sign data pri_key_file")
print("or my_rsa sign data pri_key_file sig_file hash")
exit()
data_file = sys.argv[2]
pri_key_file = sys.argv[3]
if len(sys.argv)== 5:
sig_file = sys.argv[4]
ecdsa_sign(data_file, pri_key_file, sig_file)
else:
ecdsa_sign(data_file, pri_key_file)
if sys.argv[1] == "verify":
if len(sys.argv) <= 4:
print("my_rsa verify data sig_file cert_file")
exit()
data_file = sys.argv[2]
sig_data = sys.argv[3]
pub_key_file = sys.argv[4]
ecdsa_verify(data_file, sig_data, pub_key_file)
更多推荐
已为社区贡献1条内容
所有评论(0)