def test_loopback(self): hashed_msg = SHA512.new(b("test")) signer = DSS.new(self.key_priv, 'deterministic-rfc6979') signature = signer.sign(hashed_msg) verifier = DSS.new(self.key_pub, 'deterministic-rfc6979') verifier.verify(hashed_msg, signature)
def test_loopback(self): hashed_msg = SHA512.new(b("test")) signer = DSS.new(self.key_priv, 'fips-186-3') signature = signer.sign(hashed_msg) verifier = DSS.new(self.key_pub, 'fips-186-3') verifier.verify(hashed_msg, signature)
def test_sign_verify(self): """Verify public/private method""" self.description = "can_sign() test" signer = DSS.new(self.key_priv, 'fips-186-3') self.failUnless(signer.can_sign()) signer = DSS.new(self.key_pub, 'fips-186-3') self.failIf(signer.can_sign())
def test_sign_verify(self): """Verify public/private method""" self.description = "can_sign() test" signer = DSS.new(self.key_priv, 'fips-186-3') self.assertTrue(signer.can_sign()) signer = DSS.new(self.key_pub, 'fips-186-3') self.assertFalse(signer.can_sign())
def get_DSS(key, mode, encoding): """Construct a Cryptodome specific DSS object. Args: key: The private/public key from Cryptodome backend. mode (str): The mode can be: - 'fips-186-3' - 'deterministic-rfc6979' encoding: How the signature is encoded. Values are: - 'binary' - 'der' Returns: DSS object: DSS object from Cryptodome backend. Raises: ValueError: if the mode or encoding is invalid. """ try: return DSS.new( key, mode=DSS_MODES[mode], encoding=DSS_ENCODINGS[encoding], ) except KeyError as e: raise ValueError(f"The mode or encoding is invalid: {e.args}")
async def verify_known_ecdsa_signature(name: FormalName, sig: SignaturePtrs) -> bool: global client_self_signed sig_info = sig.signature_info covered_part = sig.signature_covered_part sig_value = sig.signature_value_buf if not sig_info or sig_info.signature_type != SignatureType.SHA256_WITH_ECDSA: return False if not covered_part or not sig_value: return False try: key_bits = bytes(client_self_signed.content) except (KeyError, AttributeError): logging.debug('Cannot load pub key from received certificate') return False pk = ECC.import_key(key_bits) verifier = DSS.new(pk, 'fips-186-3', 'der') sha256_hash = SHA256.new() for blk in covered_part: sha256_hash.update(blk) try: verifier.verify(sha256_hash, bytes(sig_value)) except ValueError: return False return True
async def verify_ecdsa_signature(name: FormalName, sig: SignaturePtrs) -> bool: global local_anchor sig_info = sig.signature_info covered_part = sig.signature_covered_part sig_value = sig.signature_value_buf if not sig_info or sig_info.signature_type != SignatureType.SHA256_WITH_ECDSA: return False if not covered_part or not sig_value: return False key_name = sig_info.key_locator.name[0:] logging.debug('Extract key_name: %s', Name.to_str(key_name)) # local trust anchor pre-shared, already know server's public key key_bits = None try: key_bits = bytes(local_anchor.content) except (KeyError, AttributeError): logging.debug('Cannot load pub key from received certificate') return False pk = ECC.import_key(key_bits) verifier = DSS.new(pk, 'fips-186-3', 'der') sha256_hash = SHA256.new() for blk in covered_part: sha256_hash.update(blk) try: verifier.verify(sha256_hash, bytes(sig_value)) except ValueError: return False return True
async def verify_device_ecdsa_signature(self, name: FormalName, sig: SignaturePtrs) -> bool: sig_info = sig.signature_info covered_part = sig.signature_covered_part sig_value = sig.signature_value_buf if not sig_info or sig_info.signature_type != SignatureType.SHA256_WITH_ECDSA: return False if not covered_part or not sig_value: return False identity = [sig_info.key_locator.name[0] ] + sig_info.key_locator.name[-4:-2] logging.debug('Extract identity id from key id: %s', Name.to_str(identity)) key_bits = None try: key_bits = self.app.keychain.get(identity).default_key().key_bits except (KeyError, AttributeError): logging.error('Cannot find pub key from keychain') return False pk = ECC.import_key(key_bits) verifier = DSS.new(pk, 'fips-186-3', 'der') sha256_hash = SHA256.new() for blk in covered_part: sha256_hash.update(blk) logging.debug(bytes(sig_value)) logging.debug(len(bytes(sig_value))) try: verifier.verify(sha256_hash, bytes(sig_value)) except ValueError: return False return True
def is_valid_transaction(xact): for i in [ 'time', 'from', 'to', 'amount', 'transaction_fee', 'block_id', 'transaction_id', 'message', 'signature' ]: if i not in xact: print(f'transaction missing required field {i}') return False if xact['from'] is None: return True # this may be a valid block reward try: print('decoding sign bytes') sign = bytes.fromhex(xact['signature']) print('importing key') pub_key = ECC.import_key(xact['from']) hashes = [] print('hashing transaction') for field in [ 'time', 'from', 'to', 'amount', 'transaction_fee', 'block_id', 'transaction_id', 'message' ]: hashes.extend(fieldhash(xact[field])) hashes = b''.join(hashes) h = SHA256.new(hashes) print('verifying transaction') verifier = DSS.new(key, 'fips-186-3') verifier.verify(h, sign) except: print('Checking transaction failed.') traceback.print_exc() return False return True
def createTransaction(key, **kwargs): transaction = collections.OrderedDict() transaction_type = None if all(k in kwargs for k in ('user', 'command')): transaction_type = 0 elif all(k in kwargs for k in ('response_to', 'result', 'error')): transaction_type = 1 else: raise Exception('Invalid transaction fields.') transaction[u'ts'] = time.time() transaction[u'type'] = transaction_type transaction[u'from'] = bson.binary.Binary(key.public_key().export_key(format='DER')) if transaction_type == 0: transaction[u'user'] = kwargs['user'] transaction[u'command'] = kwargs['command'] if transaction_type == 1: transaction[u'response_to'] = bson.binary.Binary(str(kwargs['response_to'])) transaction[u'result'] = kwargs['result'] transaction[u'error'] = kwargs['error'] transaction_data = bson.BSON.encode(transaction, codec_options=bson.codec_options.CodecOptions(document_class=collections.OrderedDict)) transaction_hash = SHA256.new(transaction_data) signer = DSS.new(key, 'fips-186-3') transaction_signature = signer.sign(transaction_hash) return (transaction_signature, transaction_data)
def checkBlock(key, block): validFields = (u'last', u'ts', u'trans') try: #Check if exactly one block entry if len(block) != 1: raise Exception('Invalid number of entries.') #Check Signature blockSig = str(block.keys()[0]) blockHash = SHA256.new(str(block.values()[0])) verifier = DSS.new(key, 'fips-186-3') verifier.verify(blockHash, blockSig) #Check Fields blockData = decodeBlockData(block.values()[0]) if not all(k in blockData for k in validFields): raise Exception('Missing fields.') if not all((k in validFields) for k in blockData): raise Exception('Invalid fields.') #Check 'ts' if not isinstance(blockData[u'ts'], (int, long, float)): raise Exception('Invalid Timestamp.') #Check 'last' if not isinstance(blockData[u'last'], bson.binary.Binary): raise Exception('Invalid LastBlock format.') if not len(blockData[u'last'])==64: raise Exception('Invalid LastBlock length.') #Check 'trans' if not isinstance(blockData[u'trans'], (tuple,list)): raise Exception('Invalid Transactions.') for t in blockData[u'trans']: if not transactions.checkTransaction(t): raise Exception('Invalid transaction in block.') return True except: return False
def DSA_3072(file_name): print() print('DSA 3072 for ' + file_name + ': ') #KEY GENERATION t1 = datetime.now() key = DSA.generate(3072) t2 = datetime.now() key_speed = t2 - t1 print('TIME TAKEN FOR KEY GENERATION:(micro seconds) ' + str(key_speed.microseconds)) f = open("DSA3072_CSE565.pem", "wb") f.write(key.publickey().export_key()) f.close() #SIGNING with open(file_name + ".txt", "r") as myfile: data = myfile.read() plaintext = bytes(data, 'utf-8') hash_gen = SHA256.new(plaintext) signer = DSS.new(key, 'fips-186-3') t1 = datetime.now() signature = signer.sign(hash_gen) t2 = datetime.now() sign_time = t2 - t1 print('TIME TAKEN TO SIGN:(micro seconds) ' + str(sign_time.microseconds)) #VERIFIER f = open("DSA3072_CSE565.pem", "r") hash_gen = SHA256.new(plaintext) public_key = DSA.import_key(f.read()) verifier = DSS.new(public_key, 'fips-186-3') try: t1 = datetime.now() verifier.verify(hash_gen, signature) t2 = datetime.now() verify_time = t2 - t1 print('TIME TAKEN TO VERIFY:(micro seconds) ' + str(verify_time.microseconds)) print("THE SIGNATURE MATCHES! The message is authentic") except ValueError: print("The message is not authentic.") statinfo = os.stat(file_name + ".txt") size = statinfo.st_size sign_byte = sign_time.microseconds / size verify_byte = verify_time.microseconds / size print("TIME TO SIGN PER BYTE: " + str(sign_byte)) print("TIME TO VERIFY PER BYTE: " + str(verify_byte))
def verify(self, pkt): _, _, _, sig_ptrs = parse_data(pkt) pub_key = ECC.import_key(self.pub_key) verifier = DSS.new(pub_key, 'fips-186-3', 'der') h = SHA256.new() for content in sig_ptrs.signature_covered_part: h.update(content) verifier.verify(h, bytes(sig_ptrs.signature_value_buf))
def check_signatures(self, key): for image in self.signable_nodes: raw_sig = self.__fdt_get_binary(f'{image}/signature', 'value') raw_bin = self.__fdt_get_binary(image, 'data') sha = SHA256.new(raw_bin) verifier = DSS.new(key, 'fips-186-3') verifier.verify(sha, bytes(raw_sig))
def sign_transaction(self): """ Sign transaction with private key """ private_key = ECC.import_key(binascii.unhexlify(self.sender_private_key)) signer = DSS.new(private_key, 'fips-186-3') h = SHA256.new(str(self.to_dict()).encode('utf8')) return binascii.hexlify(signer.sign(h)).decode('ascii')
def sign_data(data, key): ''' param: string to be signed return: base64 encoded signature ''' hash_obj = SHA256.new(data.encode('utf-8')) signer = DSS.new(key, 'fips-186-3') signature = signer.sign(hash_obj) return b64encode(signature)
def generate_ecdsa(key, nonce_or_iv): ec_key = ECC.import_key(key) signer = DSS.new(ec_key, 'deterministic-rfc6979') def do_computation(msg: bytes): h = SHA256.new(msg) signature = signer.sign(h) return do_computation
def write_signature_value(self, wire: VarBinaryStr, contents: List[VarBinaryStr]) -> int: h = SHA256.new() for blk in contents: h.update(blk) signature = DSS.new(self.key, 'fips-186-3', 'der').sign(h) real_len = len(signature) wire[:real_len] = signature return real_len
def generate_dsa(key, nonce_or_iv): dsa_key = DSA.import_key(key) signer = DSS.new(dsa_key, 'fips-186-3') def do_computation(msg: bytes): h = SHA256.new(msg) signature = signer.sign(h) return do_computation
async def verify_ecdsa_signature(name: FormalName, sig: SignaturePtrs) -> bool: global trust_anchor logging.debug("Validating certificate %s", Name.to_str(name)) sig_info = sig.signature_info covered_part = sig.signature_covered_part sig_value = sig.signature_value_buf if not sig_info or sig_info.signature_type != SignatureType.SHA256_WITH_ECDSA: return False if not covered_part or not sig_value: return False key_name = sig_info.key_locator.name[0:] logging.debug('Extracting key_name: ', Name.to_str(key_name)) # check it's testbed root key_bits = None if Name.to_str(key_name) == Name.to_str(trust_anchor.name[:-2]): logging.debug('Reaching the trust anchor, begin to return') key_bits = bytes(trust_anchor.content) else: try: cert_name, meta_info, content, raw_packet = await app.express_interest( key_name, must_be_fresh=True, can_be_prefix=True, lifetime=6000, need_raw_packet=True, validator=verify_ecdsa_signature) # certificate itself is a Data packet cert = parse_certificate(raw_packet) # load public key from the data content key_bits = None try: key_bits = bytes(content) except (KeyError, AttributeError): logging.debug('Cannot load pub key from received certificate') return False except InterestNack as e: logging.debug(f'Nacked with reason={e.reason}') except InterestTimeout: logging.debug(f'Timeout') except InterestCanceled: logging.debug(f'Canceled') except ValidationFailure: logging.debug(f'Data failed to validate') pk = ECC.import_key(key_bits) verifier = DSS.new(pk, 'fips-186-3', 'der') sha256_hash = SHA256.new() for blk in covered_part: sha256_hash.update(blk) try: verifier.verify(sha256_hash, bytes(sig_value)) except ValueError: logging.debug('Certificate validation failed! %s', Name.to_str(name)) return False logging.debug('Certificate validated! %s', Name.to_str(name)) return True
def verify_ecdsa(pub_key: ECC.EccKey, sig_ptrs: SignaturePtrs) -> bool: verifier = DSS.new(pub_key, 'fips-186-3', 'der') h = SHA256.new() for content in sig_ptrs.signature_covered_part: h.update(content) try: verifier.verify(h, bytes(sig_ptrs.signature_value_buf)) return True except ValueError: return False
def test_negative_unapproved_hashes(self): """Verify that unapproved hashes are rejected""" from Cryptodome.Hash import SHA1 self.description = "Unapproved hash (SHA-1) test" hash_obj = SHA1.new() signer = DSS.new(self.key_priv, 'fips-186-3') self.assertRaises(ValueError, signer.sign, hash_obj) self.assertRaises(ValueError, signer.verify, hash_obj, b("\x00") * 40)
def test2(self): for sig in self.signatures: tk = sig.test_key key = DSA.construct([tk.y, tk.g, tk.p, tk.q, tk.x], False) signer = DSS.new(key, 'deterministic-rfc6979') hash_obj = sig.module.new(sig.message) result = signer.sign(hash_obj) self.assertEqual(sig.result, result)
def read_trust_anchor(self): ta_path = os.path.abspath(os.getenv('GIT_NDN_TRUST_ANCHOR')) with open(ta_path, 'rb') as f: cert = f.read() ta_name, _, key_bits, _ = enc.parse_data(cert, with_tl=True) user_name = bytes(enc.Component.get_value(ta_name[-5])).decode() key_name = bytes(enc.Component.get_value(ta_name[-3])).hex() self.trust_anchor_name = (user_name, key_name) pub_key = ECC.import_key(bytes(key_bits)) self.trust_anchor_verifier = DSS.new(pub_key, 'fips-186-3', 'der') logging.info(f'Trust anchor loaded: {enc.Name.to_str(ta_name)}')
def verify_message(self, message): """verify message integrity""" signature = message['signature'] del message['signature'] h = SHA256.new(message.encode()) verifier = DSS.new(message['key'], 'fips-186-3') try: verifier.verify(h, signature) return True except ValueError: return False
def sign_data(data): ''' param: string to be signed return: base64 encoded signature ''' f_key = open(private_key_loc).read() key = DSA.import_key(f_key, passphrase=secret) hash_obj = SHA256.new(data.encode('utf-8')) signer = DSS.new(key, 'fips-186-3') signature = signer.sign(hash_obj) return b64encode(signature)
def encodeTransaction(key,transaction): try: transactionData = bson.BSON.encode(transaction, codec_options=bson.codec_options.CodecOptions(document_class=collections.OrderedDict)) transactionHash = SHA256.new(transactionData) signer = DSS.new(key, 'fips-186-3') transactionSignature = signer.sign(transactionHash) t = (transactionSignature, transactionData) if checkTransaction(t): return t else: raise Exception('Invalid transaction.') except: raise Exception('Invalid transaction or key.')
def DSA_sign(plaintext, key): ''' Создание цифровой подписи для сообщения plaintext закрытым ключом key по стандарту DSS (алгоритм DSA). Обратите внимание, что для одного и того же сообщения с одним и тем же ключом алгоритм DSA будет создавать отличающиеся байтовые строки подписи - это особенность алгоритма. ''' hash_obj = SHA256.new(plaintext) signer = DSS.new(key, 'fips-186-3') signature = signer.sign(hash_obj) return signature
def verify(self, sig_ptrs: enc.SignaturePtrs) -> bool: if (sig_ptrs.signature_info is None or sig_ptrs.signature_info.key_locator is None or sig_ptrs.signature_info.key_locator.name is None): logging.info(f'No signature') return False user_name = bytes( enc.Component.get_value( sig_ptrs.signature_info.key_locator.name[-3])).decode() key_name = bytes( enc.Component.get_value( sig_ptrs.signature_info.key_locator.name[-1])).hex() if (user_name, key_name) == self.trust_anchor_name: verifier = self.trust_anchor_verifier else: try: cert = self.repo.read_file( f'refs/users/{user_name[:2]}/{user_name}', f'KEY/{key_name}.cert') except KeyError as e: if e.args[0] == 0: logging.warning(f'Repo {e.args[1]} does not exist') if e.args[0] == 1: logging.warning(f'User {user_name} does not exist') elif e.args[0] == 2: logging.warning( f'Certificate {user_name}/KEY/{key_name}.cert does not exist' ) return False try: _, _, key_bits, _ = enc.parse_data(cert, with_tl=True) pub_key = ECC.import_key(bytes(key_bits)) verifier = DSS.new(pub_key, 'fips-186-3', 'der') except (ValueError, IndexError, KeyError): logging.warning( f'Certificate {user_name}/KEY/{key_name}.cert is malformed' ) return False h = SHA256.new() for content in sig_ptrs.signature_covered_part: h.update(content) try: verifier.verify(h, bytes(sig_ptrs.signature_value_buf)) except ValueError: logging.info( f'Unable to verify the signature: signed by {user_name}/KEY/{key_name}' ) return False logging.debug(f'Verification passed') return True
def DSA_check_sign(plaintext, signature, pub_key): ''' Проверка цифровой подписи signature для соообщения plaintext открытым ключом pub_key по стандарту DSS ''' hash_obj = SHA256.new(plaintext) verifier = DSS.new(pub_key, 'fips-186-3') try: verifier.verify(hash_obj, signature) print("DSS. Сообщение достоверно") return True except ValueError: print("DSS. Сообщение недостоверно") return False
def checkTransaction(transaction): validTypes = (0,1) type0Fields = ('ts', 'type', 'from', 'command', 'user') type1Fields = ('ts', 'type', 'from', 'response_to', 'result', 'error') try: # Check if exactly one block entry if len(transaction) != 2: raise Exception('Invalid number of entries.') #Check Signature transactionSig = str(transaction[0]) transactionData = decodeTransaction(transaction) key = ECC.import_key(transactionData[u'from']) transactionHash = SHA256.new(str(transaction[1])) verifier = DSS.new(key, 'fips-186-3') verifier.verify(transactionHash, transactionSig) #Check Fields if ((transactionData[u'type'] == 0) and any(k not in type0Fields for k in transactionData)): raise Exception('Invalid type or fields.') if ((transactionData[u'type'] == 0) and (not all(k in transactionData for k in type0Fields))): raise Exception('Missing fields.') if ((transactionData[u'type'] == 1) and any(k not in type1Fields for k in transactionData)): raise Exception('Invalid type or fields.') if ((transactionData[u'type'] == 1) and (not all(k in transactionData for k in type1Fields))): raise Exception('Missing fields.') #Check 'type' if not(transactionData[u'type'] in validTypes): raise Exception('Invalid Type.') #Check 'ts' if not isinstance(transactionData[u'ts'], (int, long, float)): raise Exception('Invalid Timestamp.') if transactionData[u'type'] == 0: #Check 'command' if not isinstance(transactionData[u'command'], (unicode, str)): raise Exception('Invalid Command.') if transactionData[u'command'] == '': raise Exception('Invalid Command.') #Check 'user' if not isinstance(transactionData[u'user'], (unicode, str)): raise Exception('Invalid User.') if transactionData[u'user'] == '': raise Exception('Invalid User.') if transactionData[u'type'] == 1: #Check 'response_to' if not isinstance(transactionData[u'response_to'], (bson.binary.Binary, str)): raise Exception('Invalid Response Identifier.') #Check 'result' if not isinstance(transactionData[u'result'], (unicode, str)): raise Exception('Invalid Result.') #Check 'error' if not isinstance(transactionData[u'error'], (unicode, str)): raise Exception('Invalid Error.') return True except: return False
def test_verify(self, tv): self._id = "Wycheproof DSA Test #" + str(tv.id) hashed_msg = tv.hash_module.new(tv.msg) signer = DSS.new(tv.key, 'fips-186-3', encoding='der') try: signature = signer.verify(hashed_msg, tv.sig) except ValueError as e: if tv.warning: return assert not tv.valid else: assert tv.valid self.warn(tv)
def test_asn1_encoding(self): """Verify ASN.1 encoding""" self.description = "ASN.1 encoding test" hash_obj = SHA256.new() signer = DSS.new(self.key_priv, 'fips-186-3', 'der') signature = signer.sign(hash_obj) # Verify that output looks like a DER SEQUENCE self.assertEqual(bord(signature[0]), 48) signer.verify(hash_obj, signature) # Verify that ASN.1 parsing fails as expected signature = bchr(7) + signature[1:] self.assertRaises(ValueError, signer.verify, hash_obj, signature)
def test_asn1_encoding(self): """Verify ASN.1 encoding""" self.description = "ASN.1 encoding test" hash_obj = SHA1.new() signer = DSS.new(self.key_priv, 'fips-186-3', 'der') signature = signer.sign(hash_obj) # Verify that output looks like a SEQUENCE self.assertEqual(bord(signature[0]), 48) signer.verify(hash_obj, signature) # Verify that ASN.1 parsing fails as expected signature = bchr(7) + signature[1:] self.assertRaises(ValueError, signer.verify, hash_obj, signature)
def test_verify(self, tv): self._id = "Wycheproof ECDSA Test #%d (%s)" % (tv.id, tv.comment) hashed_msg = tv.hash_module.new(tv.msg) signer = DSS.new(tv.key, 'fips-186-3', encoding='der') try: signature = signer.verify(hashed_msg, tv.sig) except ValueError as e: if tv.warning: return if tv.comment == "k*G has a large x-coordinate": return assert not tv.valid else: assert tv.valid self.warn(tv)
def test1(self): q = 0x4000000000000000000020108A2E0CC0D99F8A5EFL x = 0x09A4D6792295A7F730FC3F2B49CBC0F62E862272FL p = 2 * q + 1 y = pow(2, x, p) key = DSA.construct([pow(y, 2, p), 2L, p, q, x], False) signer = DSS.new(key, 'deterministic-rfc6979') # Test _int2octets self.assertEqual(hexlify(signer._int2octets(x)), b("009a4d6792295a7f730fc3f2b49cbc0f" "62e862272f")) # Test _bits2octets h1 = SHA256.new(b("sample")).digest() self.assertEqual(hexlify(signer._bits2octets(h1)), b("01795edf0d54db760f156d0dac04c032" "2b3a204224"))
if isinstance(tv, basestring): res = re.match("\[mod = L=([0-9]+), N=([0-9]+), ([a-zA-Z0-9-]+)\]", tv) hash_name = res.group(3).replace("-", "") hash_module = load_hash_by_name(hash_name) continue if hasattr(tv, "p"): modulus = tv.p generator = tv.g suborder = tv.q continue hash_obj = hash_module.new(tv.msg) key = DSA.construct([bytes_to_long(x) for x in tv.y, generator, modulus, suborder], False) verifier = DSS.new(key, 'fips-186-3') def positive_test(self, verifier=verifier, hash_obj=hash_obj, signature=tv.r+tv.s): verifier.verify(hash_obj, signature) def negative_test(self, verifier=verifier, hash_obj=hash_obj, signature=tv.r+tv.s): self.assertRaises(ValueError, verifier.verify, hash_obj, signature) if tv.result == 'p': setattr(FIPS_DSA_Tests, "test_verify_positive_%d" % idx, positive_test) else: setattr(FIPS_DSA_Tests, "test_verify_negative_%d" % idx, negative_test) test_vectors_sign = load_tests(("Cryptodome", "SelfTest", "Signature", "test_vectors", "DSA"), "FIPS_186_3_SigGen.txt",
def test_data_rfc6979(self): signer = DSS.new(self.key_priv, 'deterministic-rfc6979') for message, k, r, s, module in self.signatures: hash_obj = module.new(message) result = signer.sign(hash_obj) self.assertEqual(r + s, result)