Add sign with key pem
This commit is contained in:
parent
b06a2c0ffb
commit
c44df24629
|
@ -6,7 +6,6 @@ import datetime
|
|||
import getpass
|
||||
from pathlib import Path
|
||||
|
||||
import xmlsec
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography import x509
|
||||
|
@ -20,15 +19,17 @@ from conf import TOKEN
|
|||
|
||||
class SATCertificate(object):
|
||||
|
||||
def __init__(self, cer=b'', key=b'', password=''):
|
||||
def __init__(self, cer=b'', key=b'', pem=b'', password=''):
|
||||
self._error = ''
|
||||
self._init_values()
|
||||
self._get_data_cer(cer)
|
||||
self._get_data_key(key, password)
|
||||
self._get_data_pem(pem)
|
||||
|
||||
def _init_values(self):
|
||||
self._rfc = ''
|
||||
self._serial_number = ''
|
||||
self._serial_number2 = ''
|
||||
self._not_before = None
|
||||
self._not_after = None
|
||||
self._is_fiel = False
|
||||
|
@ -37,9 +38,11 @@ class SATCertificate(object):
|
|||
self._cer_pem = ''
|
||||
self._cer_txt = ''
|
||||
self._key_enc = b''
|
||||
self._key_pem = b''
|
||||
self._p12 = b''
|
||||
self._cer_modulus = 0
|
||||
self._key_modulus = 0
|
||||
self._issuer = ''
|
||||
return
|
||||
|
||||
def __str__(self):
|
||||
|
@ -66,9 +69,12 @@ class SATCertificate(object):
|
|||
obj = x509.load_der_x509_certificate(cer, default_backend())
|
||||
self._rfc = obj.subject.get_attributes_for_oid(
|
||||
NameOID.X500_UNIQUE_IDENTIFIER)[0].value.split(' ')[0]
|
||||
self._serial_number2 = obj.serial_number
|
||||
self._serial_number = '{0:x}'.format(obj.serial_number)[1::2]
|
||||
self._not_before = obj.not_valid_before
|
||||
self._not_after = obj.not_valid_after
|
||||
self._issuer = ','.join([i.rfc4514_string() for i in obj.issuer])
|
||||
|
||||
now = datetime.datetime.utcnow()
|
||||
self._is_valid_time = (now > self.not_before) and (now < self.not_after)
|
||||
if not self._is_valid_time:
|
||||
|
@ -81,6 +87,7 @@ class SATCertificate(object):
|
|||
self._cer_pem = obj.public_bytes(serialization.Encoding.PEM).decode()
|
||||
self._cer_txt = ''.join(self._cer_pem.split('\n')[1:-2])
|
||||
self._cer_modulus = obj.public_key().public_numbers().n
|
||||
|
||||
return
|
||||
|
||||
def _get_data_key(self, key, password):
|
||||
|
@ -126,6 +133,14 @@ class SATCertificate(object):
|
|||
)
|
||||
return key_pem
|
||||
|
||||
def _get_data_pem(self, pem):
|
||||
if not pem:
|
||||
return
|
||||
|
||||
self._key_pem = serialization.load_pem_private_key(
|
||||
pem, None, backend=default_backend())
|
||||
return
|
||||
|
||||
# Not work
|
||||
def _get_p12(self):
|
||||
obj = serialization.pkcs12.serialize_key_and_certificates('test',
|
||||
|
@ -139,7 +154,26 @@ class SATCertificate(object):
|
|||
firma = private_key.sign(data, padding.PKCS1v15(), hashes.SHA256())
|
||||
return base64.b64encode(firma).decode()
|
||||
|
||||
def _sign_with_pem(self, data, name_hash):
|
||||
if name_hash == 'sha256':
|
||||
type_hash = hashes.SHA256()
|
||||
elif name_hash == 'sha1':
|
||||
type_hash = hashes.SHA1()
|
||||
|
||||
firma = self._key_pem.sign(data, padding.PKCS1v15(), type_hash)
|
||||
return base64.b64encode(firma).decode()
|
||||
|
||||
def sign_sha1(self, data, password=''):
|
||||
if self._key_pem:
|
||||
return self._sign_with_pem(data, 'sha1')
|
||||
|
||||
private_key = self._get_key(password)
|
||||
firma = private_key.sign(data, padding.PKCS1v15(), hashes.SHA1())
|
||||
return base64.b64encode(firma).decode()
|
||||
|
||||
def sign_xml(self, tree):
|
||||
import xmlsec
|
||||
|
||||
node = xmlsec.tree.find_node(tree, xmlsec.constants.NodeSignature)
|
||||
ctx = xmlsec.SignatureContext()
|
||||
key = xmlsec.Key.from_memory(self.key_pem, xmlsec.constants.KeyDataFormatPem)
|
||||
|
@ -157,6 +191,10 @@ class SATCertificate(object):
|
|||
def serial_number(self):
|
||||
return self._serial_number
|
||||
|
||||
@property
|
||||
def serial_number2(self):
|
||||
return self._serial_number2
|
||||
|
||||
@property
|
||||
def not_before(self):
|
||||
return self._not_before
|
||||
|
@ -197,6 +235,10 @@ class SATCertificate(object):
|
|||
def key_enc(self):
|
||||
return self._key_enc
|
||||
|
||||
@property
|
||||
def issuer(self):
|
||||
return self._issuer
|
||||
|
||||
@property
|
||||
def p12(self):
|
||||
return self._get_p12()
|
||||
|
@ -204,52 +246,3 @@ class SATCertificate(object):
|
|||
@property
|
||||
def error(self):
|
||||
return self._error
|
||||
|
||||
|
||||
def main(args):
|
||||
# ~ contra = getpass.getpass('Introduce la contraseña del archivo KEY: ')
|
||||
contra = '12345678a'
|
||||
if not contra.strip():
|
||||
msg = 'La contraseña es requerida'
|
||||
print(msg)
|
||||
return
|
||||
|
||||
path_cer = Path(args.cer)
|
||||
path_key = Path(args.key)
|
||||
|
||||
if not path_cer.is_file():
|
||||
msg = 'El archivo CER es necesario'
|
||||
print(msg)
|
||||
return
|
||||
|
||||
if not path_key.is_file():
|
||||
msg = 'El archivo KEY es necesario'
|
||||
print(msg)
|
||||
return
|
||||
|
||||
cer = path_cer.read_bytes()
|
||||
key = path_key.read_bytes()
|
||||
cert = SATCertificate(cer, key, contra)
|
||||
|
||||
if cert.error:
|
||||
print(cert.error)
|
||||
else:
|
||||
print(cert)
|
||||
return
|
||||
|
||||
|
||||
def _process_command_line_arguments():
|
||||
parser = argparse.ArgumentParser(description='CFDI Certificados')
|
||||
|
||||
help = 'Archivo CER'
|
||||
parser.add_argument('-c', '--cer', help=help, default='')
|
||||
help = 'Archivo KEY'
|
||||
parser.add_argument('-k', '--key', help=help, default='')
|
||||
|
||||
args = parser.parse_args()
|
||||
return args
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = _process_command_line_arguments()
|
||||
main(args)
|
Loading…
Reference in New Issue