def read_keys(): global P_K_enc, P_K_shop, P_ca, K_K_enc try: """key = open('./keys/P_enc--loyaltyEncryptionPublic.key').read() P_K_enc = PublicKey.RSA.importKey(key) key = open('./keys/K_enc--loyaltyEncryptionPrivate.key').read() P_K_enc = PublicKey.RSA.importKey(key) """ pub = RSA2.load_pub_key("./keys/P_enc--loyaltyEncryptionPublic.key") priv = RSA2.load_key("./keys/K_enc--loyaltyEncryptionPrivate.key") P_K_enc = (pub, priv) key = open('./keys/P_CA--CAPublicKey.key').read() P_ca = PublicKey.RSA.importKey(key) #key = open('./keys/Attrapez-les-tous_RSAprivate.key').read() #P_K_shop = PublicKey.RSA.importKey(key) P_K_shop = RSA2.load_key("./keys/Attrapez-les-tous_RSAprivate.key") except IOError: print """ Need the files: ./keys/P_enc--loyaltyEncryptionPublic.key ./keys/K_enc--loyaltyEncryptionPrivate.key ./keys/P_CA--CAPublicKey.key ./keys/Attrapez-les-tous_RSAprivate.key """ exit(-1)
def __get_keys(self): """ Returns a key objects for the master """ if os.path.exists(self.rsa_path): key = RSA.load_key(self.rsa_path) log.debug("Loaded master key: {0}".format(self.rsa_path)) else: log.info("Generating keys: {0}".format(self.opts["pki_dir"])) gen_keys(self.opts["pki_dir"], "master", self.opts["keysize"], self.opts.get("user")) key = RSA.load_key(self.rsa_path) return key
def __get_keys(self): ''' Returns a key objects for the master ''' if os.path.exists(self.rsa_path): key = RSA.load_key(self.rsa_path) log.debug('Loaded master key: {0}'.format(self.rsa_path)) else: log.info('Generating keys: {0}'.format(self.opts['pki_dir'])) gen_keys(self.opts['pki_dir'], 'master', 4096) key = RSA.load_key(self.rsa_path) return key
def sign_attachment(self): if not crypto_install: raise MissingError( "ERROR IMPORTING M2Crypto, if not installed, " "please install it.\nGet it here:\n" "https://pypi.python.org/pypi/M2Crypto" ) params = self.env["ir.config_parameter"] def _get_key(): signature_key = params.sudo().get_param("attachment_signature_key", default="") return signature_key def gimmepw(*args): signature_passphrase = params.sudo().get_param("attachment_signature_passphrase", default="") return str(signature_passphrase) key = _get_key() pkey = RSA.load_key(key, gimmepw) value = self.datas sha256_val = hashlib.sha256(value).digest() signature = pkey.sign(sha256_val) file_name = self.datas_fname + ".signature" self.signature_id = self.create( { "name": file_name, "datas": base64.encodestring(base64.encodestring(signature)), "datas_fname": file_name, "res_model": self._name, "res_id": self.id, "is_signature": True, } ).id
def __init__(self, pub_key, priv_key, ca_cert, passphrase): """ Create a Certification Subject Object. Arguments: pub_key: file system path of the Subject's Public Key. priv_key: file system path of the Subject's Private Key (encrypted). ca_cert: file system path of the Certification Authority's Certificate. passphrase: Symmetric key for priv_key decryption. """ def getPassphrase(*args): """ Callback for private key decrypting. """ return str(passphrase.encode('utf-8')) self.pub_key = RSA.load_pub_key(pub_key.encode('utf-8')) self.priv_key = RSA.load_key(priv_key.encode('utf-8'), getPassphrase) self.ca_cert = X509.load_cert(ca_cert.decode('utf-8')) # Private key for signing self.signEVP = EVP.PKey() self.signEVP.assign_rsa(self.priv_key) # CA Key for validations self.verifyEVP = EVP.PKey() self.verifyEVP.assign_rsa(self.ca_cert.get_pubkey().get_rsa())
def load_key(): """ Given key path loads as a RSA private key object. """ pkey = RSA.load_key(PRIVATE_KEY) return pkey
def loadCert(name): """Load a cert and its private key and return them both.""" p = name + ".pem" c = X509.load_cert(p) k = EVP.PKey() k.assign_rsa(RSA.load_key(p, callback=pwCb)) return c, k
def m2c_key(arg1, arg2): try: rsa = RSA.gen_key(1024, 3, lambda *agr:None) pub_bio = BIO.MemoryBuffer() priv_bio = BIO.MemoryBuffer() rsa.save_pub_key_bio(pub_bio) rsa.save_key_bio(priv_bio, None) pub_file = arg1 # pub_file = arg1 + 'pub.pem' private_file = arg2 # private_file = arg2 + 'private.pem' open(pub_file,'w').write(pub_bio.read_all()) open(private_file,'w').write(priv_bio.read_all()) pub_key = RSA.load_pub_key(pub_file) priv_key = RSA.load_key(private_file) message = 'opzoon' encrypted = pub_key.public_encrypt(message, RSA.pkcs1_padding) decrypted = priv_key.private_decrypt(encrypted, RSA.pkcs1_padding) if decrypted==message: #os.popen("rm -rf m2crypto_gen_key.py") pass else: os.popen("rm -rf *.pem") print "Key generation failed,please try again!" raise Exception("Key generation failed,please try again!") except Exception,e: os.popen("rm -rf *.pem") raise Exception("Key generation failed,please try again!")
def get_dbpass(self): def passphrase_callback(): return "eucalyptus" d = hashlib.sha256() d.update("eucalyptus") pk = RSA.load_key(self.cloudpk_file,passphrase_callback) self.db_pass = binascii.hexlify(pk.sign(d.digest(),algo="sha256"))
def _resign_whitelist(self, expiry_date): old_whitelist = os.path.join(self.dir, ".cvmfswhitelist") new_whitelist = os.path.join(self.dir, ".cvmfswhitelist.new") wl_hash = hashlib.sha1() new_wl = open(new_whitelist, 'w+') old_wl = open(old_whitelist) pos = old_wl.tell() while True: line = old_wl.readline() if len(line) >= 3 and line[0:3] == 'E20': #fails in 85 years line = 'E' + expiry_date.strftime("%Y%m%d%H%M%S") + '\n' if line[0:2] == "--": break if pos == old_wl.tell(): raise Exception("Signature not found in whitelist") wl_hash.update(line) new_wl.write(line) pos = old_wl.tell() old_wl.close() new_wl.write("--\n") new_wl.write(wl_hash.hexdigest()) new_wl.write("\n") key = RSA.load_key(self.master_key) sig = key.private_encrypt(wl_hash.hexdigest(), RSA.pkcs1_padding) new_wl.write(sig) new_wl.close() os.rename(new_whitelist, old_whitelist)
def response(context, request): req = request slcsResp = req.POST['CertificateRequestData'] session_key = req.POST['SessionKey'] print req.GET originURL=request.GET['url'] # Decrpyt session Key with host private key (RSA) encrypted = unhexlify(session_key) priv_key = RSA.load_key(get_settings()['host_privkey']) session_key = priv_key.private_decrypt(encrypted, RSA.pkcs1_padding) # Decrypt message with session key (AES) a = AES.new(session_key) plaintext = a.decrypt(unhexlify(slcsResp)) # remove AES padding n = ord(plaintext[-1]) # last byte contains number of padding bytes if n > AES.block_size or n > len(plaintext): raise Exception('invalid padding') print plaintext try: certificate = slcs_handler(StringIO(plaintext[:-n])) print "cert = " + str(certificate) except SLCSException, e: # TODO add error handling print "Exception: " + str(e) pass
def test_loadkey(self): rsa = RSA.load_key(self.privkey) assert len(rsa) == 1024 assert rsa.e == '\000\000\000\003\001\000\001' # aka 65537 aka 0xf4 self.assertEqual(rsa.n, "\x00\x00\x00\x81\x00\xcde!\x15\xdah\xb5`\xce[\xd6\x17d\xba8\xc1I\xb1\xf1\xber\x86K\xc7\xda\xb3\x98\xd6\xf6\x80\xae\xaa\x8f!\x9a\xefQ\xdeh\xbb\xc5\x99\x01o\xebGO\x8e\x9b\x9a\x18\xfb6\xba\x12\xfc\xf2\x17\r$\x00\xa1\x1a \xfc/\x13iUm\x04\x13\x0f\x91D~\xbf\x08\x19C\x1a\xe2\xa3\x91&\x8f\xcf\xcc\xf3\xa4HRf\xaf\xf2\x19\xbd\x05\xe36\x9a\xbbQ\xc86|(\xad\x83\xf2Eu\xb2EL\xdf\xa4@\x7f\xeel|\xfcU\x03\xdb\x89'") self.assertRaises(AttributeError, getattr, rsa, 'nosuchprop') assert rsa.check_key() == 1
def test_sign_and_verify(self): """ Testing signing and verifying digests """ algos = {'sha1': '', 'ripemd160': '', 'md5': ''} if m2.OPENSSL_VERSION_NUMBER >= 0x90800F: algos['sha224'] = '' algos['sha256'] = '' algos['sha384'] = '' algos['sha512'] = '' message = b"This is the message string" digest = hashlib.sha1(message).digest() rsa = RSA.load_key(self.privkey) rsa2 = RSA.load_pub_key(self.pubkey) for algo in algos.keys(): signature = rsa.sign(digest, algo) # assert signature == algos[algo], # 'mismatched signature with algorithm %s: # signature=%s' % (algo, signature) verify = rsa2.verify(digest, signature, algo) self.assertEqual(verify, 1, 'verification failed with algorithm %s' % algo)
def __init__(self, key_path): """ Instantiates the RSA signature method instance. """ super(oauth2.SignatureMethod, self).__init__() self.key_path = key_path self.RSA = RSA.load_key(key_path)
def rsa_sign(self, xml): "Sign an XML document using RSA" # Sign the SHA1 digest of the signed xml using RSA cipher pkey = RSA.load_key(self.key) signature = pkey.sign(hashlib.sha1(xml).digest()) # build the mapping (placeholders) to create the final xml signed message return base64.b64encode(signature)
def __get_priv_key(self): ''' Retruns a private key object for the master ''' key = None try: key = RSA.load_key(self.rsa_path, callback=foo_pass) self.opts['logger'].debug('Loaded master key: ' + self.rsa_path) except: self.opts['logger'].info('Generating master key: ' + self.rsa_path) gen = RSA.gen_key(2048, 1) gen.save_key(self.rsa_path, callback=foo_pass) gen.save_pub_key(self.pub_path) key = RSA.load_key(self.rsa_path, callback=foo_pass) os.chmod(self.rsa_path, 256) return key
def decrypt_string(self, encrypted_string, private_key_path, encoded=False): user_priv_key = RSA.load_key(private_key_path) string_to_decrypt = encrypted_string if encoded: string_to_decrypt = base64.b64decode(encrypted_string) return user_priv_key.private_decrypt(string_to_decrypt, RSA.pkcs1_padding)
def sign(self,text_to_be_hashed=""): filename = '/path/to/mykey.pem' priv_key = RSA.load_key(filename) digest = hashlib.sha256(text_to_be_hashed).digest() signature=priv_key.sign(digest, 'sha256') result=base64.b64encode(signature) return result
def get_modulus_exponent_from_cert_and_pkey_pemfile(cert_path='/tmp/xmppwebid_cert.pem', key_path='/tmp/xmppwebid_key.key'): """Get the modulus and exponent of RSA key from a PEM Certificate and key files m2.rsa_get_e(rsa.rsa) return something like '\x00\x00\x00\x03\x01\x00\x01' so to get the decimal value (65537), two crufty methods :param cert_path: certificate path :type cert_path: string :param key_path: key path :type key_path: string :return: tuple(modulus, exponent) :rtype: tuple (hex, int) .. TODO:: replace the exponent method with something cleaner """ cert=X509.load_cert(cert_path) pubkey = cert.get_pubkey() modulus = pubkey.get_modulus() pkey_rsa = RSA.load_key(key_path) e = m2.rsa_get_e(pkey_rsa.rsa) # exponent = int(eval(repr(e[-3:]).replace('\\x', '')),16) exponent = int(''.join(["%2.2d" % ord(x) for x in e[-3:]]),16) return modulus, exponent
def setUpClass(cls): super(ConsumerAuthTest, cls).setUpClass() cls.ROLES = ROLES cls.PROFILE = PROFILE cls.rsa_primary = RSA.load_key('/usr/share/pulp_auto/tests/data/fake-consumer.pem') cls.rsa_secondary = RSA.load_key('/usr/share/pulp_auto/tests/data/fake-consumer-secondary.pem') bio_fd = BIO.MemoryBuffer() cls.rsa_primary.save_pub_key_bio(bio_fd) cls.pub_pem_primary = bio_fd.getvalue() bio_fd = BIO.MemoryBuffer() cls.rsa_secondary.save_pub_key_bio(bio_fd) cls.pub_pem_secondary = bio_fd.getvalue() cls.repo, cls.importer, cls.distributor = create_yum_repo(cls.pulp, **[repo for repo in cls.ROLES.repos if repo.type == 'rpm'][0]) cls.consumer = Consumer.register(cls.pulp, cls.__name__ + '_consumer', rsa_pub=cls.pub_pem_primary) cls.agent = Agent(pulp_auto.handler, PROFILE=pulp_auto.handler.profile.PROFILE) cls.qpid_handle = QpidHandle(cls.ROLES.qpid.url, cls.consumer.id, auth=Authenticator(signing_key=cls.rsa_primary, verifying_key=cls.pulp.pubkey))
def create(self, alt_name=None): """Sign a certificate request; return a certificate.""" if alt_name: self.alt_name = common.validate_domain(alt_name) req = self._do_req() issuer = self.signca._gen_x509_name(self.signca.ca_cn) cert = X509.X509() cert.set_version(2) serialnumber = self.signca._increment_serial() cert.set_serial_number(serialnumber) cert.set_issuer_name(issuer) cert.set_subject(req.get_subject()) certpubkey = req.get_pubkey() cert.set_pubkey(certpubkey) pubkey_fprint = self._gen_pubkey_fingerprint(certpubkey) cert = self._set_duration(cert) # Create and add certificate extensions cert = self._add_extensions(cert, pubkey_fprint) # Sign the cert with the CA key cakey = RSA.load_key(self.signca.ca_key_file, callback = self.signca._pass_callback) capkey = EVP.PKey() capkey.assign_rsa(cakey, 1) cert.sign(capkey, 'sha1') self._save_cert(cert) result = self.get() return result
def test_singlehost_rename_old_certs(self): """Test repeated requests for the same host to make sure we aren't overwriting files. https://jira.opensciencegrid.org/browse/OSGPKI-137 https://jira.opensciencegrid.org/browse/OSGPKI-139 """ hostname = 'test.' + DOMAIN initial_req = OIM() rc, _, _, msg = initial_req.gridadmin_request('--hostname', hostname) self.assertEqual(rc, 0, "Failed to request initial certificate\n%s" % msg) # Request another cert that will move the previous cert out of the way rc, stdout, _, msg = OIM().gridadmin_request('--hostname', hostname) self.assertEqual(rc, 0, "Failed to request second certificate\n%s" % msg) # Verify that the moved key/cert pair is the same as in the initial request try: # TODO: The format of the output is not text wrapped like it should be. # When that is fixed, the regex should be updated old_cert_path = re.search(r'Renaming existing file from.*to (.*)', stdout).group(1) old_key_path = re.search(r'Renaming existing key from.*to (.*)', stdout).group(1) except AttributeError: self.fail('Failed to move old cert or key\n' + msg) # Cert objects don't seem to handle equality checks well, compare the pem versions old_cert = X509.load_cert(old_cert_path).as_pem() self.assertEqual(initial_req.certs[0].as_pem(), old_cert, 'Renamed cert is not the same as the initial cert\n' + msg) # Need to grab pem formats without a cipher to compare keys old_key = RSA.load_key(old_key_path, OIM.simple_pass_callback) old_key_pem = old_key.as_pem(cipher=None, callback=OIM.simple_pass_callback) initial_key_pem = initial_req.keys[0].as_pem(cipher=None, callback=OIM.simple_pass_callback) self.assertEqual(initial_key_pem, old_key_pem, 'Renamed key is not the same as the initial key\n' + msg)
def create_rsa_keyring(passphrase_callback, key_size=2048, exponent=65537): """ Return a new RSA keyring as tuple (<public key>, <private key>) @param passphrase_callback: A Python callable object that is invoked during key generation; its usual purpose is to provide visual feedback. You must load a randpool file before calling this method with Rand.load_file('randpool', -1). After calling the method, you must save the randpool file with Rand.save_file('randpool') @type passphrase_callback: Callback @param key_size: Key length, in bits @type key_size: Integer @param exponent: The RSA public exponent @type exponent: Integer """ keyring = RSA.gen_key(key_size, exponent) privkey_filename = get_secure_filename() pubkey_filename = get_secure_filename() keyring.save_key(privkey_filename, callback=passphrase_callback) keyring.save_pub_key(pubkey_filename) privkey = RSA.load_key(privkey_filename, callback=passphrase_callback) pubkey = RSA.load_pub_key(pubkey_filename) os.unlink(privkey_filename) os.unlink(pubkey_filename) return (pubkey, privkey)
def __init__(self, keyfile=None): # All callbacks. self.callbacks = { "request": None, "response": None, "request_encrypted": None, "response_encrypted": None, "client_hello": None, "server_hello": None, "certificate": None, "server_hello_done": None, "client_key_exchange": None, "change_cipher_spec": None, "session_ticket": None, "server_key_exchange": None, } # Only the callbacks for metadata, only useful internally. self.__metadata_callbacks = [k for k in self.callbacks if k != "request" or k != "response"] self.keypair = None if keyfile: # XXX: Support callback? self.keypair = RSA.load_key(keyfile) self.parsers = {} self.sids = {}
def clean_old_key(rsa_path): ''' Read in an old m2crypto key and save it back in the clear so pycrypto can handle it ''' def foo_pass(self, data=''): return 'foo' mkey = RSA.load_key(rsa_path, callback=foo_pass) try: os.remove(rsa_path) except (IOError, OSError): pass # Set write permission for minion.pem file - reverted after saving the key if sys.platform == 'win32': import win32api import win32con win32api.SetFileAttributes(rsa_path, win32con.FILE_ATTRIBUTE_NORMAL) try: mkey.save_key(rsa_path, None) except IOError: log.error( ('Failed to update old RSA format for key {0}, future ' 'releases may not be able to use this key').format(rsa_path) ) # Set read-only permission for minion.pem file if sys.platform == 'win32': import win32api import win32con win32api.SetFileAttributes(rsa_path, win32con.FILE_ATTRIBUTE_READONLY) return mkey
def __init__(self, keyfile=None): # All callbacks. self.callbacks = { 'request': None, 'response': None, 'request_encrypted': None, 'response_encrypted': None, 'client_hello': None, 'server_hello': None, 'certificate': None, 'server_hello_done': None, 'client_key_exchange': None, 'change_cipher_spec': None, 'session_ticket': None, 'server_key_exchange': None } # Only the callbacks for metadata, only useful internally. self.__metadata_callbacks = [ k for k in self.callbacks if k != 'request' or k != 'response' ] self.keypair = None if keyfile: # XXX: Support callback? self.keypair = RSA.load_key(keyfile) self.parsers = {} self.sids = {}
def get_keys(self): ''' Returns a key objects for the minion ''' # Make sure all key parent directories are accessible user = self.opts.get('user', 'root') salt.utils.verify.check_path_traversal(self.opts['pki_dir'], user) if os.path.exists(self.rsa_path): key = RSA.load_key(self.rsa_path) log.debug('Loaded minion key: {0}'.format(self.rsa_path)) else: log.info('Generating keys: {0}'.format(self.opts['pki_dir'])) gen_keys(self.opts['pki_dir'], 'minion', 4096) key = RSA.load_key(self.rsa_path) return key
def helper_get_client_certificate(self): """Get a generic client certificate and its public-private key.""" (cakey, cacert) = self.helper_get_certificate() key = RSA.load_key(cakey) cakey = EVP.PKey() cakey.assign_rsa(key) cacert = X509.load_cert(cacert) keylocation = '/tmp/nosetest_individuation.client.key' certlocation = '/tmp/nosetest_individuation.client.pem' try: os.stat(keylocation) os.stat(certlocation) except OSError: (key, pkey) = self.helper_generate_key() f = open(keylocation, 'w') f.write(key.as_pem(cipher=None)) f.close() req = self.helper_generate_certificate_request(pkey) cert = self.helper_sign_certificate(cakey, cacert, req) f = open(certlocation, 'w') f.write(cert.as_pem()) f.close() return (keylocation, certlocation)
def main(keylen, hashalg): global rsa, dgst # this exists ONLY for speed testing Rand.load_file('randpool.dat', -1) pvtkeyfilename = 'rsa%dpvtkey.pem' % (keylen) pubkeyfilename = 'rsa%dpubkey.pem' % (keylen) if makenewkey: print ' making and saving a new key' rsa = RSA.gen_key(keylen, exponent) rsa.save_key(pvtkeyfilename, None ) # no pswd callback rsa.save_pub_key(pubkeyfilename) else: print ' loading an existing key' rsa = RSA.load_key(pvtkeyfilename) print ' rsa key length:', len(rsa) if not rsa.check_key(): raise 'key is not initialised' # since we are testing signing and verification, let's not # be fussy about the digest. Just make one. md = EVP.MessageDigest(hashalg) md.update('can you spell subliminal channel?') dgst = md.digest() print ' hash algorithm: %s' % hashalg if showdigest: print ' %s digest: \n%s' % (hashalg, base64.encodestring(dgst)) test(rsa, dgst) # test_asn1(rsa, dgst) test_speed(rsa, dgst) Rand.save_file('randpool.dat')
def set_private_key(self, keyfile=None, **kwargs): """ Load the rsa private key and return True, if available, otherwise return False. 'irreversible' does not have a private key so: >>> keyfile = self._get_keypaths().get(algorithm).get(mode).get('private', None) >>> keyfile >>> None Keyword Arguments: - algorithm -- rsa, aes (default: no default). - mode -- the mode dictionary key. For example local (default: no default). """ algorithm = kwargs.get('algorithm', self.algorithm) mode = kwargs.get('mode', self.mode) self.private_key = None if not keyfile: # keyfile not specified, so get default for algorithm and mode if not algorithm or not mode: raise EncryptionKeyError('Algorithm and mode must be set ' 'before attempting to set the ' 'private key') keyfile = self._get_keypaths().get(algorithm).get(mode).get('private', None) # either load from IS_PRELOADED or from file if isinstance(self._get_preloaded_keypaths().get(algorithm).get(mode).get('private', None), RSA.RSA): self.private_key = (self._get_preloaded_keypaths().get(algorithm).get(mode).get('private', None)) else: try: if keyfile: self.private_key = RSA.load_key(keyfile) logger.info('successfully loaded {0} {1} private ' 'key'.format(algorithm, mode)) except: # if you need a warning here, do so in the subclass pass return self.private_key is not None
print (certificado)''' # ->> Cadena Original xml_file = open(PATH + "/facturas/no_procesados/XML_Ejemplo_33.xml", "r") dom = ET.parse(xml_file) xslt = ET.parse(PATH + "/xslt/cadenaoriginal_3_3.xslt") transform = ET.XSLT(xslt) cadena_original = transform(dom) cadena_original = base64.b64encode(cadena_original) #print(ET.tostring(newxml, pretty_print = True)) #print(str(cadena_original)) #file = open("cadena_original.txt", "w") #file.write(str(cadena_original)) # ->> Sello key = RSA.load_key(PATH + "/certKey/key.pem") digest = hashlib.new('sha256', str(cadena_original).encode('utf-8')).digest() sello = base64.b64encode(key.sign(digest, "sha256")) print(sello.decode('utf-8')) #file = open("sello.txt", "w") #file.write(sello.decode('utf-8')) # Para leer xml y pasarlo a String '''xml_file = open(PATH + "\\XML_Ejemplo_33.xml","rb").read() #dom = ET.fromstring(xml_file) print(xml_file.decode('utf-8'))''' #Parse XML y actualizar valor de atributo '''tree = ET.parse(PATH + "\\XML_Ejemplo_33.xml") root = tree.getroot() #root.attrib['Version'] = "1"
def test_loadkey_pp(self): rsa = RSA.load_key(self.privkey2, self.pp_callback) self.assertEqual(len(rsa), 1024) self.assertEqual(rsa.e, b'\000\000\000\003\001\000\001') # aka 65537 aka 0xf4 self.assertEqual(rsa.check_key(), 1)
def test_loadkey_pp_bad_cb(self): with self.assertRaises(RSA.RSAError): RSA.load_key(self.privkey2, self.pp2_callback)
def add_signature(iface,certpem,pkeypem): try: module = [ name for name in os.listdir(".") if name.endswith(".mod") ][0] except IndexError: raise ValueError, "La carpeta actual no contiene un fichero de modulo" modulename, ext = os.path.splitext(module) signatures_file = modulename + ".signatures" if not os.path.exists(signatures_file): print "INFO: El fichero %s no existe, será creado." % signatures_file xmlsign_root = new_signatures_file(iface) else: # Parse certificates xml here: xmlparser = etree.XMLParser(ns_clean=True, remove_blank_text=True,remove_comments=False,remove_pis=True) newtree = etree.parse(signatures_file, parser = xmlparser) xmlsign_root = newtree.getroot() xmlsign_root.text = None cert1 = add_certificate(iface,certpem) checksum_file = module_checksum(iface) check_opts = create_signature_options(iface) signed_document = etree.SubElement(xmlsign_root, "signed-document") signed_document.set("check","true") xmlcertificate = etree.SubElement(signed_document,"signer-certificate") xmlcertificate.set("O",u8(cert1.get_subject().O)) xmlcertificate.set("CN",u8(cert1.get_subject().CN)) xmlcertificate.set("emailAddress",u8(cert1.get_subject().emailAddress)) xmlcertificate.set("fingerprint-sha256",cert1.get_fingerprint('sha256').lower()) xmldocument = etree.SubElement(signed_document,"document") xmldocument.set("format","tag:name:sha256") hashobj = hashlib.sha256() hash_file(hashobj, checksum_file) checksum_file_hash = hashobj.hexdigest() hashobj = hashlib.sha256() hashobj.update(check_opts) check_opts_hash = hashobj.hexdigest() xmlchecksumfile = etree.SubElement(xmldocument,"file") xmlchecksumfile.set("name","checksums.xml") xmlchecksumfile.set("href",checksum_file) xmlchecksumfile.set("sha256",checksum_file_hash) xmlchecksumoptions = etree.SubElement(xmldocument,"data") xmlchecksumoptions.set("name","checksum-options.xml") xmlchecksumoptions.set("format","base64") xmlchecksumoptions.set("sha256",check_opts_hash) xmlchecksumoptions.text = b64encode(check_opts) data = "" for node in xmldocument: data += "%s:%s:%s\n" % (node.tag, node.get("name"), node.get("sha256")) hashobj = hashlib.sha256() hashobj.update(data) data_hash = hashobj.hexdigest() xmldocument.set("sha256", data_hash) cert1 = X509.load_cert(certpem) cert1_pkey = cert1.get_pubkey() cert1_pkey.reset_context(md='sha256') rsa1 = RSA.load_key(pkeypem) sevp = EVP.PKey(md='sha256') sevp.assign_rsa(rsa1) sevp.sign_init() sevp.sign_update(data) signature = sevp.sign_final() xmlsignature = etree.SubElement(signed_document,"signature",format="SHA-256:RSASSA-PKCS1v1.5:base64") xmlsignature.text = b64encode(signature) cert1_pkey.verify_init() cert1_pkey.verify_update(data) verification = cert1_pkey.verify_final(signature) if verification != 1: print "ERROR: Verificacion de firma erronea, devolvio %d. Compruebe que la firma corresponde al certificado." % verification return # Eliminar firmas previas que sean del mismo firmante. for signed_doc in xmlsign_root.xpath("signed-document[signer-certificate/@fingerprint-sha256='%s']" % cert1.get_fingerprint('sha256').lower()): doc_sha256 = signed_doc.xpath("document/@sha256")[0] if doc_sha256 == data_hash: continue print "INFO: Se elimina firma antigua del mismo certificado." xmlsign_root.remove(signed_doc) xmltext = etree.tostring(xmlsign_root, pretty_print=True) f1 = open(signatures_file, "w") f1.write(xmltext) f1.close() print "Se ha escrito el fichero %s" % signatures_file
def facturar_rep(factura_id): logger.info('Task facturar iniciada') # Configurar redondeo getcontext().rounding = ROUND_HALF_UP # Calcular fecha actual fecha = timezone.localtime() # Consultar contrato factura = models.Factura.objects.get(id=factura_id) # Calcular impuestos # Cargar certificado CSD cer = X509.load_cert(settings.CSD_CER, X509.FORMAT_DER) # Cargar llave privada CSD key = RSA.load_key(settings.CSD_KEY) # Obtener numero de serie serial_number = '{:x}'.format(int(cer.get_serial_number())).decode('hex') # Obtener folio folio_conf = models.Configuracion.objects.get(nombre='U_FOLIO') folio_conf.valor = folio_conf.valor + 1 folio_conf.save() nsmap = { 'cfdi': 'http://www.sat.gob.mx/cfd/3', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'pago10': 'http://www.sat.gob.mx/Pagos', } attrib = { '{http://www.w3.org/2001/XMLSchema-instance}schemaLocation': 'http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd http://www.sat.gob.mx/Pagos http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd' } # Nodo cfdi:Comprobante cfdi = etree.Element('{http://www.sat.gob.mx/cfd/3}Comprobante', nsmap=nsmap, attrib=attrib) cfdi.set('Version', '3.3') cfdi.set('Serie', settings.SERIE_REP) cfdi.set('Folio', str(folio_conf.valor)) cfdi.set('Fecha', fecha.isoformat()[:19]) cfdi.set('NoCertificado', serial_number) cfdi.set('Certificado', base64.b64encode(cer.as_der())) cfdi.set('SubTotal', '0') cfdi.set('Moneda', 'XXX') cfdi.set('Total', '0') cfdi.set('TipoDeComprobante', 'P') cfdi.set('LugarExpedicion', settings.CODIGO_POSTAL) # Nodo cfdi:Emisor emisor = etree.SubElement(cfdi, '{http://www.sat.gob.mx/cfd/3}Emisor') emisor.set('Rfc', settings.RFC) emisor.set('Nombre', settings.RAZON_SOCIAL) emisor.set('RegimenFiscal', settings.REGIMEN_FISCAL) # Nodo cfdi:Receptor receptor = etree.SubElement(cfdi, '{http://www.sat.gob.mx/cfd/3}Receptor') receptor.set('Rfc', factura.rfc_cliente) receptor.set('Nombre', factura.nombre_cliente) receptor.set('UsoCFDI', 'P01') # Nodo cfdi:Conceptos conceptos = etree.SubElement(cfdi, '{http://www.sat.gob.mx/cfd/3}Conceptos') # Nodo cfdi:Concepto concepto = etree.SubElement(conceptos, '{http://www.sat.gob.mx/cfd/3}Concepto') concepto.set('ClaveProdServ', '84111506') concepto.set('Cantidad', '1') concepto.set('ClaveUnidad', 'ACT') concepto.set('Descripcion', 'Pago') concepto.set('ValorUnitario', '0.000000') concepto.set('Importe', '0.00') # Nodo cfdi:Conceptos complemento = etree.SubElement(cfdi, '{http://www.sat.gob.mx/cfd/3}Complemento') # Nodo pago10:Pagos pagos = etree.SubElement(complemento, '{http://www.sat.gob.mx/Pagos}Pagos') pagos.set('Version', '1.0') # Nodo pago10:Pagos pago = etree.SubElement(pagos, '{http://www.sat.gob.mx/Pagos}Pago') pago.set('FechaPago', '{}T01:00:00'.format(factura.fecha_pago.isoformat())) pago.set('FormaDePagoP', factura.forma_pago_rep) pago.set('MonedaP', settings.MONEDA) pago.set('Monto', '{}'.format(factura.total)) pago.set('NumOperacion', factura.num_operacion) # Nonda pago10:DoctoRelacionado docto_relacionado = etree.SubElement( pago, '{http://www.sat.gob.mx/Pagos}DoctoRelacionado') docto_relacionado.set('IdDocumento', '{}'.format(factura.uuid)) docto_relacionado.set('Serie', factura.serie) docto_relacionado.set('Folio', '{}'.format(factura.folio)) docto_relacionado.set('MonedaDR', settings.MONEDA) docto_relacionado.set('MetodoDePagoDR', factura.contrato.metodo_pago) docto_relacionado.set('NumParcialidad', '1') docto_relacionado.set('ImpSaldoAnt', '{}'.format(factura.total)) docto_relacionado.set('ImpPagado', '{}'.format(factura.total)) docto_relacionado.set('ImpSaldoInsoluto', '0') # Cargar xslt para generar cadena original xslt = etree.XSLT(etree.parse(settings.PATH_XLST)) # Generar cadena original cadena_original = xslt(cfdi) # sacar hash a cadena original digest = hashlib.new('sha256', str(cadena_original)).digest() # Firmar digest de cadena original sign = key.sign(digest, "sha256") # Pasar sello de Bytes a b64 sello = base64.b64encode(sign) # Agrefar sello a documento xml cfdi.set('Sello', sello) # Generar archivo xml xml = etree.tostring(cfdi, pretty_print=True) # Format token token = 'bearer %s' % str(settings.PAC_TOKEN) # Crear mensaje multiparte para adjuntar archivo m = MultipartEncoder(fields={ 'xml': ('xml', xml, 'text/xml', { 'Content-Transfer-Encoding': 'binary' }) }) # Crear headers headers = {'Content-Type': m.content_type, 'Authorization': token} # Realizar request tipo post al pac req = requests.post(settings.PAC_URL, headers=headers, data=m.to_string()) # Verificar request if req.status_code != 200: raise Exception(u'id_factura: {} Error {}'.format( factura.id, req.json())) # Extraer xml xml_timbrado = req.json()['data']['cfdi'].encode('utf-8') # Parsear XML timpado cfdi_timbrado = etree.fromstring(xml_timbrado) # Buscar UUID uuid = cfdi_timbrado.find('{http://www.sat.gob.mx/cfd/3}Complemento').find( '{http://www.sat.gob.mx/TimbreFiscalDigital}TimbreFiscalDigital' ).attrib.get('UUID') # Generar PDF xml_dict = xmltodict.parse(xml_timbrado)['cfdi:Comprobante'] cbb_url = 'https://verificacfdi.facturaelectronica.sat.gob.mx/' \ 'default.aspx?id={0}re={1}&rr={2}&tt={3}&fe={4}'.format( uuid, settings.RFC, factura.rfc_cliente, factura.total, sello[(len(sello) - 8):], ) # Generar codigo qr de cbb qrdata = qrcode.make(cbb_url) raw = StringIO() qrdata.save(raw) cbb = b64encode(raw.getvalue()) # Renderizar HTML html = get_template('webapp/factura-pago-pdf.html').render({ 'xml': xml_dict, 'cadena_original': cadena_original, 'cbb': cbb, }) # Generar PDF pdf = pdfkit.from_string(html, False, options={ 'page-size': 'Letter', 'encoding': "UTF-8", 'quiet': '', }) # Guardar factura en base de datos factura.uuid_rep = uuid factura.xml_rep = ContentFile(xml_timbrado, name='{0}.xml'.format(uuid)) factura.pdf_rep = ContentFile(pdf, name='{0}.pdf'.format(uuid)) factura.save() # Enviar correo html_email = get_template('webapp/factura-correo.txt').render( {'factura': factura}) msg = EmailMessage('{} Nuevo REP {} {} Generada'.format( settings.RAZON_SOCIAL, factura.serie, factura.folio), html_email, settings.DEFAULT_FROM_EMAIL, to=[factura.correo_cliente], reply_to=[settings.TENANT_EMAIL], cc=[settings.TENANT_EMAIL]) msg.attach('{}_{}.xml'.format(factura.serie, factura.folio), factura.xml.read(), 'application/xml') msg.attach('{}_{}.pdf'.format(factura.serie, factura.folio), factura.pdf.read(), 'application/pdf') msg.attach('{}_{}.xml'.format(factura.serie, factura.folio), factura.xml_rep.read(), 'application/xml') msg.attach('{}_{}.pdf'.format(factura.serie, factura.folio), factura.pdf_rep.read(), 'application/pdf') msg.send() logger.info('Task facturar terminada') return factura.id
def __init__(self, rsa_key_path): with open(rsa_key_path + '.pub') as rsa_pub_file: self.public_key = rsa_pub_file.read() self.rsa_key = RSA.load_key(rsa_key_path)
for alpha2 in countrynames: coll = countries[alpha2] # struct regdb_file_reg_country output.write( struct.pack('>ccxBI', str(alpha2[0]), str(alpha2[1]), coll.dfs_region, reg_rules_collections[coll.permissions])) if len(sys.argv) > 3: # Load RSA only now so people can use this script # without having those libraries installed to verify # their SQL changes from M2Crypto import RSA # determine signature length key = RSA.load_key(sys.argv[3]) hash = hashlib.sha1() hash.update(output.getvalue()) sig = key.sign(hash.digest()) # write it to file siglen.set(len(sig)) # sign again hash = hashlib.sha1() hash.update(output.getvalue()) sig = key.sign(hash.digest()) output.write(sig) else: siglen.set(0) outfile = open(sys.argv[1], 'w')
def decodeClientKey(encodedKey): priKeyFile = return_data_for_server_key('priKey') priv = RSA.load_key(priKeyFile) decrypted = priv.private_decrypt(base64.b64decode(encodedKey), RSA.pkcs1_padding) return decrypted
def test_loadkey_pp(self): rsa = RSA.load_key(self.privkey2, self.pp_callback) assert len(rsa) == 1024 assert rsa.e == '\000\000\000\003\001\000\001' # aka 65537 aka 0xf4 assert rsa.check_key() == 1
class Command(BaseCommand): """ Creates the tincd config files and Server.tinc object. This method must be called by a superuser """ def __init__(self, *args, **kwargs): # Options are defined in an __init__ method to support swapping out # custom user models in tests. super(Command, self).__init__(*args, **kwargs) default_username = get_default_celeryd_username() self.option_list = BaseCommand.option_list + ( make_option('--username', dest='username', default=default_username, help='Specifies the login for the superuser.'), make_option( '--mgmt_prefix', dest='mgmt_prefix', default=settings.MGMT_IPV6_PREFIX, help='Mgmt prefix, the settings file will be updated.'), make_option( '--default_port', dest='default_port', default=TINC_PORT_DFLT, help='Tinc port default, the settings file will be updated.'), make_option('--address', dest='address', default='0.0.0.0', help='Tinc BindToAddress'), make_option('--net_name', dest='net_name', default=TINC_NET_NAME, help='Tinc net name'), make_option( '--nohup', dest='nohup', default=TINC_TINCD_SEND_HUP, help= 'Whether we want to send a HUP signal to tinc after an update' ' or not. It requires sudo'), make_option( '--noinput', action='store_false', dest='interactive', help= 'Tells Django to NOT prompt the user for input of any kind. ' 'You must use --username with --noinput, and must contain the ' 'cleeryd process owner, which is the user how will perform ' 'tincd updates', default=True), ) option_list = BaseCommand.option_list help = 'Creates the tincd config files and Server.tinc object' @transaction.atomic @check_root def handle(self, *args, **options): from tinc.models import TincHost, TincAddress interactive = options.get('interactive') username = options.get('username') if not interactive: # validate username if not username: raise CommandError("You must use --username with --noinput.") try: username = pwd.getpwnam(username).pw_name except KeyError: raise CommandError("Username doesn't exists.") else: # Prompt for username # Enclose this whole thing in a try/except to trap for a # keyboard interrupt and exit gracefully. prompt_username = None while prompt_username is None: if not prompt_username: input_msg = "Celeryd username" if username: input_msg += " (leave blank to use '%s')" % username value = input(input_msg + ': ') if username and value == '': value = username # validate username try: prompt_username = pwd.getpwnam(value).pw_name except KeyError, e: self.stderr.write("Error: %s" % e) prompt_username = None continue server = Server.objects.first() server_ct = ContentType.objects.get_for_model(Server) tinc_server, __ = TincHost.objects.get_or_create( object_id=server.pk, content_type=server_ct) tinc_port = options.get('default_port') tinc_address = options.get('address') tinc_net_name = options.get('net_name') mgmt_prefix = options.get('mgmt_prefix') if mgmt_prefix != settings.MGMT_IPV6_PREFIX: update_settings(MGMT_IPV6_PREFIX=mgmt_prefix, monkey_patch='controller.settings') if tinc_port != TINC_PORT_DFLT: update_settings(TINC_PORT_DFLT=tinc_port) if tinc_net_name != TINC_NET_NAME: update_settings(TINC_NET_NAME=tinc_net_name) context = { 'tincd_root': TINC_TINCD_ROOT, 'tincd_bin': TINC_TINCD_BIN, 'net_name': tinc_net_name, 'net_root': os.path.join(TINC_TINCD_ROOT, tinc_net_name), 'tinc_conf': ("BindToAddress = %s\n" "Port = %s\n" "Name = server\n" "StrictSubnets = yes" % (tinc_address, tinc_port)), 'tinc_up': tinc_server.get_tinc_up(), 'tinc_down': tinc_server.get_tinc_down(), 'mgmt_prefix': mgmt_prefix.split('::')[0], 'user': username } r = functools.partial(run, silent=False) boots = run("grep %(net_name)s %(tincd_root)s/nets.boot" % context, err_codes=[0, 1]) if boots.return_code == 1: r("echo %(net_name)s >> %(tincd_root)s/nets.boot" % context) r("mkdir -p %(net_root)s/hosts" % context) r("echo '%(tinc_conf)s' > %(net_root)s/tinc.conf" % context) r('echo "Subnet = %(mgmt_prefix)s:0:0:0:0:2/128" > %(net_root)s/hosts/server' % context) r("echo '%(tinc_up)s' > %(net_root)s/tinc-up" % context) r("echo '%(tinc_down)s' > %(net_root)s/tinc-down" % context) r("chown %(user)s %(net_root)s/hosts" % context) r("chmod +x %(net_root)s/tinc-up" % context) r("chmod +x %(net_root)s/tinc-down" % context) TincAddress.objects.get_or_create(host=tinc_server, addr=tinc_address, port=tinc_port) priv_key = os.path.join(TINC_TINCD_ROOT, tinc_net_name, 'rsa_key.priv') try: priv_key = RSA.load_key(priv_key) except: # generate a new key r('tincd -c %(net_root)s -K' % context) priv_key = RSA.load_key(priv_key) bio = BIO.MemoryBuffer() priv_key.save_pub_key_bio(bio) pub_key = bio.getvalue() tinc_server.pubkey = pub_key tinc_server.save() if options.get('nohup'): sudoers_hup = ( "%(user)s\s\s*ALL=NOPASSWD:\s\s*%(tincd_bin)s\s\s*-kHUP\s\s*-n %(net_name)s" ) % context sudoers_exists = run('grep "%s" /etc/sudoers' % sudoers_hup, err_codes=[0, 1, 2]) if sudoers_exists.return_code == 1: cmd = "%(user)s ALL=NOPASSWD: %(tincd_bin)s -kHUP -n %(net_name)s" % context r("echo '%s' >> /etc/sudoers" % cmd) elif sudoers_exists.return_code == 2: raise CommandError( 'Sudo is not installed on your system. \n' 'You may want to use --nohup option, so sudo will not be a requirement' ) else: update_settings(TINC_TINCD_SEND_HUP=False) self.stdout.write('Tincd server successfully created and configured.') self.stdout.write( 'NOTE: restarting the following services is required ' 'to apply updated configuration:\n' 'tincd, uwsgi, celeryd.\n' 'Please run: "sudo python manage.py restartservices" or ' 'restart them manually.')
'--ssl': (print_ssl, print_ssl_keys), '--gcrypt': (print_gcrypt, print_gcrypt_keys), } try: mode = sys.argv[1] files = sys.argv[2:-1] outfile = sys.argv[-1] except IndexError: mode = None if not mode in modes: print 'Usage: %s [%s] input-file... output-file' % (sys.argv[0], '|'.join(modes.keys())) sys.exit(2) output = open(outfile, 'w') # load key idx = 0 for f in files: try: key = RSA.load_pub_key(f) except RSA.RSAError: key = RSA.load_key(f) modes[mode][0](output, 'e_%d' % idx, key.e[4:]) modes[mode][0](output, 'n_%d' % idx, key.n[4:]) idx += 1 modes[mode][1](output, idx - 1)
def rsa_read_keypair(filename): return RSA.load_key(filename)
def get_key(self): return RSA.load_key(self.priv_key_path)
# -*- coding: utf-8 -*- import M2Crypto from M2Crypto import * from M2Crypto.EVP import Cipher from M2Crypto import m2 from M2Crypto import util enKey = "68b329da9893e34099c7d8ad5cb9c940" salt = "" from M2Crypto import RSA publicKey = 'secret/public' privateKey = 'secret/private' RSAPub = RSA.load_pub_key(publicKey) RSAPri = RSA.load_key(privateKey) from configure import enKey,RSAPub, RSAPri, salt import hashlib import json import base64 from base64 import b64encode, b64decode ENC = 1 # 加密操作 DEC = 0 # 解密操作 class SecurityTools(): rsaPub = RSAPub rsaPri = RSAPri privateKey = enKey
#!/usr/bin/env python # SWIG RPM package should be installed before installing the # M2crypto module import os import json from M2Crypto import RSA, EVP import base64 import hashlib cwd = os.path.dirname(__file__) PRIVATE_KEY = os.path.join(cwd, "private.key") pkey = RSA.load_key(PRIVATE_KEY) def signature(content): MD5 = hashlib.md5() MD5.update(content) MD5string = MD5.digest() sign = pkey.private_encrypt(MD5string, RSA.pkcs1_padding) return base64.b64encode(sign) def default_encoder(obj): return obj.__json__() def make_signature_response(out): if not isinstance(out, dict):
def test_loadkey_junk(self): with self.assertRaises(RSA.RSAError): RSA.load_key(self.errkey)
def facturar(contrato_id, descripcion=None, sub_total=None): logger.info('Task facturar iniciada') # Configurar redondeo getcontext().rounding = ROUND_HALF_UP # Calcular fecha actual fecha = timezone.localtime() # Consultar contrato contrato = models.Contrato.objects.get(id=contrato_id) # Si no se envia descripcion factura el mes correspondiente a la fecha actual if descripcion is None: sub_total = contrato.precio_mensual descripcion = u'Renta correspondiente al mes {0} del {1} {2}'.format( nombre_mes(fecha.month), fecha.year, contrato.nombre_predio) # Calcular impuestos iva_tra = (sub_total * Decimal('0.160000')).quantize(TWO_PLACES) iva_ret = Decimal('0.00') isr_ret = Decimal('0.00') if contrato.retener_impuestos: iva_ret = (sub_total * Decimal('0.106666')).quantize(TWO_PLACES) isr_ret = (sub_total * Decimal('0.100000')).quantize(TWO_PLACES) total_tra = iva_tra total_ret = (iva_ret + isr_ret).quantize(TWO_PLACES) total = ((sub_total + total_tra) - total_ret).quantize(TWO_PLACES) # Cargar certificado CSD cer = X509.load_cert(settings.CSD_CER, X509.FORMAT_DER) # Cargar llave privada CSD key = RSA.load_key(settings.CSD_KEY) # Obtener numero de serie serial_number = '{:x}'.format(int(cer.get_serial_number())).decode('hex') # Obtener folio folio_conf = models.Configuracion.objects.get(nombre='U_FOLIO') folio_conf.valor = folio_conf.valor + 1 folio_conf.save() nsmap = { 'cfdi': 'http://www.sat.gob.mx/cfd/3', 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', } attrib = { '{http://www.w3.org/2001/XMLSchema-instance}schemaLocation': 'http://www.sat.gob.mx/cfd/3' } # Nodo cfdi:Comprobante cfdi = etree.Element('{http://www.sat.gob.mx/cfd/3}Comprobante', nsmap=nsmap, attrib=attrib) cfdi.set('Version', '3.3') cfdi.set('Serie', settings.SERIE) cfdi.set('Folio', str(folio_conf.valor)) cfdi.set('Fecha', fecha.isoformat()[:19]) cfdi.set('FormaPago', contrato.forma_pago) cfdi.set('NoCertificado', serial_number) cfdi.set('Certificado', base64.b64encode(cer.as_der())) cfdi.set('SubTotal', '{}'.format(sub_total)) cfdi.set('Moneda', settings.MONEDA) cfdi.set('Total', '{}'.format(total)) cfdi.set('TipoDeComprobante', 'I') cfdi.set('MetodoPago', contrato.metodo_pago) cfdi.set('LugarExpedicion', settings.CODIGO_POSTAL) # Nodo cfdi:Emisor emisor = etree.SubElement(cfdi, '{http://www.sat.gob.mx/cfd/3}Emisor') emisor.set('Rfc', settings.RFC) emisor.set('Nombre', settings.RAZON_SOCIAL) emisor.set('RegimenFiscal', settings.REGIMEN_FISCAL) # Nodo cfdi:Receptor receptor = etree.SubElement(cfdi, '{http://www.sat.gob.mx/cfd/3}Receptor') receptor.set('Rfc', contrato.rfc_cliente) receptor.set('Nombre', contrato.nombre_cliente) receptor.set('UsoCFDI', contrato.uso_cfdi) # Nodo cfdi:Conceptos conceptos = etree.SubElement(cfdi, '{http://www.sat.gob.mx/cfd/3}Conceptos') # Nodo cfdi:Concepto concepto = etree.SubElement(conceptos, '{http://www.sat.gob.mx/cfd/3}Concepto') concepto.set('ClaveProdServ', settings.CLAVE_PROD_SERV) concepto.set('Cantidad', '1') concepto.set('ClaveUnidad', settings.CLAVE_UNIDAD) concepto.set('Descripcion', descripcion) concepto.set('ValorUnitario', '{}'.format(sub_total)) concepto.set('Importe', '{}'.format(sub_total)) # Nodo cfdi:Impuestos impuestos = etree.SubElement(concepto, '{http://www.sat.gob.mx/cfd/3}Impuestos') # Nodo cfdi:Traslados traslados = etree.SubElement(impuestos, '{http://www.sat.gob.mx/cfd/3}Traslados') # Nodo cfdi:Traslado traslado = etree.SubElement(traslados, '{http://www.sat.gob.mx/cfd/3}Traslado') traslado.set('Base', '{}'.format(sub_total)) traslado.set('Impuesto', '002') traslado.set('TipoFactor', 'Tasa') traslado.set('TasaOCuota', '0.160000') traslado.set('Importe', '{}'.format(iva_tra)) if contrato.retener_impuestos: # Nodo cfdi:Retenciones retenciones = etree.SubElement( impuestos, '{http://www.sat.gob.mx/cfd/3}Retenciones') # Nodo cfdi:Retencion IVA traslado = etree.SubElement(retenciones, '{http://www.sat.gob.mx/cfd/3}Retencion') traslado.set('Base', '{}'.format(sub_total)) traslado.set('Impuesto', '002') traslado.set('TipoFactor', 'Tasa') traslado.set('TasaOCuota', '0.106666') traslado.set('Importe', '{}'.format(iva_ret)) # Nodo cfdi:Retencion ISR retencion = etree.SubElement(retenciones, '{http://www.sat.gob.mx/cfd/3}Retencion') retencion.set('Base', '{}'.format(sub_total)) retencion.set('Impuesto', '001') retencion.set('TipoFactor', 'Tasa') retencion.set('TasaOCuota', '0.100000') retencion.set('Importe', '{}'.format(isr_ret)) if contrato.cuenta_predial is not None: cuenta_predial = etree.SubElement( concepto, '{http://www.sat.gob.mx/cfd/3}CuentaPredial') cuenta_predial.set('Numero', str(contrato.cuenta_predial)) # Nodo cfdi:Impuestos impuestos = etree.SubElement(cfdi, '{http://www.sat.gob.mx/cfd/3}Impuestos') impuestos.set('TotalImpuestosTrasladados', '{}'.format(total_tra)) if contrato.retener_impuestos: impuestos.set('TotalImpuestosRetenidos', '{}'.format(total_ret)) # Nodo cfdi:Retenciones retenciones = etree.SubElement( impuestos, '{http://www.sat.gob.mx/cfd/3}Retenciones') # Nodo cfdi:Retencion IVA retencion_iva = etree.SubElement( retenciones, '{http://www.sat.gob.mx/cfd/3}Retencion') retencion_iva.set('Impuesto', '002') retencion_iva.set('Importe', '{}'.format(iva_ret)) # Nodo cfdi:Retencion ISR retencion_isr = etree.SubElement( retenciones, '{http://www.sat.gob.mx/cfd/3}Retencion') retencion_isr.set('Impuesto', '001') retencion_isr.set('Importe', '{}'.format(isr_ret)) # Nodo cfdi:Traslados traslados = etree.SubElement(impuestos, '{http://www.sat.gob.mx/cfd/3}Traslados') # Nodo cfdi:Traslado traslado_iva = etree.SubElement(traslados, '{http://www.sat.gob.mx/cfd/3}Traslado') traslado_iva.set('Impuesto', '002') traslado_iva.set('TipoFactor', 'Tasa') traslado_iva.set('TasaOCuota', '0.160000') traslado_iva.set('Importe', '{}'.format(iva_tra)) # Cargar xslt para generar cadena original xslt = etree.XSLT(etree.parse(settings.PATH_XLST)) # Generar cadena original cadena_original = xslt(cfdi) # sacar hash a cadena original digest = hashlib.new('sha256', str(cadena_original)).digest() # Firmar digest de cadena original sign = key.sign(digest, "sha256") # Pasar sello de Bytes a b64 sello = base64.b64encode(sign) # Agrefar sello a documento xml cfdi.set('Sello', sello) # Generar archivo xml xml = etree.tostring(cfdi, pretty_print=True) # Format token token = 'bearer %s' % str(settings.PAC_TOKEN) # Crear mensaje multiparte para adjuntar archivo m = MultipartEncoder(fields={ 'xml': ('xml', xml, 'text/xml', { 'Content-Transfer-Encoding': 'binary' }) }) # Crear headers headers = {'Content-Type': m.content_type, 'Authorization': token} # Realizar request tipo post al pac req = requests.post(settings.PAC_URL, headers=headers, data=m.to_string()) # Verificar request if req.status_code != 200: raise Exception(u'id_contrato: {} Error {}'.format( contrato.id, req.json())) # Extraer xml xml_timbrado = req.json()['data']['cfdi'].encode('utf-8') # Parsear XML timpado cfdi_timbrado = etree.fromstring(xml_timbrado) # Buscar UUID uuid = cfdi_timbrado.find('{http://www.sat.gob.mx/cfd/3}Complemento').find( '{http://www.sat.gob.mx/TimbreFiscalDigital}TimbreFiscalDigital' ).attrib.get('UUID') # Generar PDF xml_dict = xmltodict.parse(xml_timbrado)['cfdi:Comprobante'] cbb_url = 'https://verificacfdi.facturaelectronica.sat.gob.mx/' \ 'default.aspx?id={0}re={1}&rr={2}&tt={3}&fe={4}'.format( uuid, settings.RFC, contrato.rfc_cliente, total, sello[(len(sello) - 8):], ) # Generar codigo qr de cbb qrdata = qrcode.make(cbb_url) raw = StringIO() qrdata.save(raw) cbb = b64encode(raw.getvalue()) # Renderizar HTML html = get_template('webapp/factura-pdf.html').render({ 'xml': xml_dict, 'cadena_original': cadena_original, 'cbb': cbb, }) # Generar PDF pdf = pdfkit.from_string(html, False, options={ 'page-size': 'Letter', 'encoding': "UTF-8", 'quiet': '', }) # Guardar factura en base de datos factura = models.Factura() factura.fecha = fecha factura.contrato = contrato factura.uuid = uuid factura.serie = settings.SERIE factura.folio = folio_conf.valor factura.nombre_cliente = contrato.nombre_cliente factura.rfc_cliente = contrato.rfc_cliente factura.correo_cliente = contrato.correo_cliente factura.concepto = descripcion factura.sub_total = sub_total factura.iva_trasladado = iva_tra factura.iva_retenido = iva_ret factura.isr_retenido = isr_ret factura.total = total factura.xml = ContentFile(xml_timbrado, name='{0}.xml'.format(uuid)) factura.pdf = ContentFile(pdf, name='{0}.pdf'.format(uuid)) factura.save() # sumar saldo en contrato contrato.saldo_contrato = contrato.saldo_contrato + total contrato.save() # Enviar correo html_email = get_template('webapp/factura-correo.txt').render( {'factura': factura}) msg = EmailMessage('{} Nueva Factura {} {} Generada'.format( settings.RAZON_SOCIAL, factura.serie, factura.folio), html_email, settings.DEFAULT_FROM_EMAIL, to=[factura.correo_cliente], reply_to=[settings.TENANT_EMAIL], cc=[settings.TENANT_EMAIL]) msg.attach('{}_{}.xml'.format(factura.serie, factura.folio), factura.xml.read(), 'application/xml') msg.attach('{}_{}.pdf'.format(factura.serie, factura.folio), factura.pdf.read(), 'application/pdf') msg.send() logger.info('Task facturar terminada') return factura.id