def test_export_openssh_compressed(self): key_file = load_file("ecc_p384_public_openssh.txt", "rt") pub_key = ECC.import_key(key_file) key_file_compressed = pub_key.export_key(format="OpenSSH", compress=True) assert len(key_file) > len(key_file_compressed) self.assertEquals(pub_key, ECC.import_key(key_file_compressed))
def test_compressed_curve(self): # Compressed P-521 curve (Y-point is even) # openssl ecparam -name secp521r1 -genkey -noout -conv_form compressed -out /tmp/a.pem # openssl ec -in /tmp/a.pem -text -noout pem1 = """-----BEGIN EC PRIVATE KEY----- MIHcAgEBBEIAnm1CEjVjvNfXEN730p+D6su5l+mOztdc5XmTEoti+s2R4GQ4mAv3 0zYLvyklvOHw0+yy8d0cyGEJGb8T3ZVKmg2gBwYFK4EEACOhgYkDgYYABAHzjTI1 ckxQ3Togi0LAxiG0PucdBBBs5oIy3df95xv6SInp70z+4qQ2EltEmdNMssH8eOrl M5CYdZ6nbcHMVaJUvQEzTrYxvFjOgJiOd+E9eBWbLkbMNqsh1UKVO6HbMbW0ohCI uGxO8tM6r3w89/qzpG2SvFM/fvv3mIR30wSZDD84qA== -----END EC PRIVATE KEY-----""" # Compressed P-521 curve (Y-point is odd) pem2 = """-----BEGIN EC PRIVATE KEY----- MIHcAgEBBEIB84OfhJluLBRLn3+cC/RQ37C2SfQVP/t0gQK2tCsTf5avRcWYRrOJ PmX9lNnkC0Hobd75QFRmdxrB0Wd1/M4jZOWgBwYFK4EEACOhgYkDgYYABAAMZcdJ 1YLCGHt3bHCEzdidVy6+brlJIbv1aQ9fPQLF7WKNv4c8w3H8d5a2+SDZilBOsk5c 6cNJDMz2ExWQvxl4CwDJtJGt1+LHVKFGy73NANqVxMbRu+2F8lOxkNp/ziFTbVyV vv6oYkMIIi7r5oQWAiQDrR2mlrrFDL9V7GH/r8SWQw== -----END EC PRIVATE KEY-----""" key1 = ECC.import_key(pem1) low16 = int(key1.pointQ.y % 65536) self.assertEqual(low16, 0x38a8) key2 = ECC.import_key(pem2) low16 = int(key2.pointQ.y % 65536) self.assertEqual(low16, 0x9643)
def test_compressed_curve(self): # Compressed P-384 curve (Y-point is even) # openssl ecparam -name secp384p1 -genkey -noout -conv_form compressed -out /tmp/a.pem # openssl ec -in /tmp/a.pem -text -noout pem1 = """-----BEGIN EC PRIVATE KEY----- MIGkAgEBBDAM0lEIhvXuekK2SWtdbgOcZtBaxa9TxfpO/GcDFZLCJ3JVXaTgwken QT+C+XLtD6WgBwYFK4EEACKhZANiAATs0kZMhFDu8DoBC21jrSDPyAUn4aXZ/DM4 ylhDfWmb4LEbeszXceIzfhIUaaGs5y1xXaqf5KXTiAAYx2pKUzAAM9lcGUHCGKJG k4AgUmVJON29XoUilcFrzjDmuye3B6Q= -----END EC PRIVATE KEY-----""" # Compressed P-384 curve (Y-point is odd) pem2 = """-----BEGIN EC PRIVATE KEY----- MIGkAgEBBDDHPFTslYLltE16fHdSDTtE/2HTmd3M8mqy5MttAm4wZ833KXiGS9oe kFdx9sNV0KygBwYFK4EEACKhZANiAASLIE5RqVMtNhtBH/u/p/ifqOAlKnK/+RrQ YC46ZRsnKNayw3wATdPjgja7L/DSII3nZK0G6KOOVwJBznT/e+zudUJYhZKaBLRx /bgXyxUtYClOXxb1Y/5N7txLstYRyP0= -----END EC PRIVATE KEY-----""" key1 = ECC.import_key(pem1) low16 = int(key1.pointQ.y % 65536) self.assertEqual(low16, 0x07a4) key2 = ECC.import_key(pem2) low16 = int(key2.pointQ.y % 65536) self.assertEqual(low16, 0xc8fd)
def test_import_private_pem_encrypted(self): for algo in "des3", "aes128", "aes192", "aes256", "aes256_gcm": key_file = load_file("ecc_p521_private_enc_%s.pem" % algo) key = ECC.import_key(key_file, "secret") self.assertEqual(self.ref_private, key) key = ECC.import_key(tostr(key_file), b"secret") self.assertEqual(self.ref_private, key)
def import_public_key(public_key): """ Import a plain text public key and make it into an ECC object :param public_key: the public key as a string :return: an ECC key object """ return ECC.import_key(public_key)
def test_export_public_der_compressed(self): key_file = load_file("ecc_p521_public.der") pub_key = ECC.import_key(key_file) key_file_compressed = pub_key.export_key(format="DER", compress=True) key_file_compressed_ref = load_file("ecc_p521_public_compressed.der") self.assertEqual(key_file_compressed, key_file_compressed_ref)
def test_unsupported_curve(self): # openssl ecparam -name secp224r1 -genkey -noout -out strange-curve.pem -conv_form uncompressed curve = """-----BEGIN EC PRIVATE KEY----- MGgCAQEEHEi7xTHW+5oT8wgpjoEKV7uwMuY8rt2YUZe4j1SgBwYFK4EEACGhPAM6 AATJgfOG+Bnki8robpNM8MtArji43GU9up4B0x9sVhqB+fZP+hXgV9ITN7YX4E/k gVnJp9EBND/tHQ== -----END EC PRIVATE KEY-----""" from Crypto.PublicKey.ECC import UnsupportedEccFeature try: ECC.import_key(curve) except UnsupportedEccFeature as uef: assert("1.3.132.0.33" in str(uef)) else: assert(False)
def decrypt_with_ecc(private_ecc_key, random_pubkey_str, nonce, ctx, tag): """Takes elliptic curve isntance (private_ecc_key) and a byte string (message), and decrypts the ciphertext (ctx) after verifying the tag. """ assert isinstance(private_ecc_key, ECC.EccKey), \ "private_ecc_key should be ECC key. Got {}" \ .format(type(private_ecc_key)) # parse the ciphertext random_ecc_key = ECC.import_key(random_pubkey_str) new_point = random_ecc_key.pointQ * private_ecc_key.d h = SHA256.new(str(new_point.x)) h.update(str(new_point.y)) key = h.digest() if not nonce: nonce = os.urandom(16) aes_engine = AES.new(key=key, mode=AES.MODE_EAX, nonce=nonce) msg = '' try: msg = aes_engine.decrypt_and_verify(ctx, tag) except ValueError: print "The tag verification failed. Means: ciphertext has been "\ "tampered or key is incorrect" return msg
def test_import_x509_der(self): key_file = load_file("ecc_p521_x509.der") key = ECC._import_der(key_file, None) self.assertEqual(self.ref_public, key) key = ECC.import_key(key_file) self.assertEqual(self.ref_public, key)
def test_import_openssh(self): key_file = load_file("ecc_p521_public_openssh.txt") key = ECC._import_openssh(key_file) self.assertEqual(self.ref_public, key) key = ECC.import_key(key_file) self.assertEqual(self.ref_public, key)
def test_export_public_pem_compressed(self): key_file = load_file("ecc_p384_public.pem", "rt").strip() pub_key = ECC.import_key(key_file) key_file_compressed = pub_key.export_key(format="PEM", compress=True) key_file_compressed_ref = load_file("ecc_p384_public_compressed.pem", "rt").strip() self.assertEqual(key_file_compressed, key_file_compressed_ref)
def test_import_private_pkcs8_clear(self): key_file = load_file("ecc_p521_private_p8_clear.der") key = ECC._import_der(key_file, None) self.assertEqual(self.ref_private, key) key = ECC.import_key(key_file) self.assertEqual(self.ref_private, key)
def test_import_private_pkcs8_encrypted_1(self): key_file = load_file("ecc_p521_private_p8.der") key = ECC._import_der(key_file, "secret") self.assertEqual(self.ref_private, key) key = ECC.import_key(key_file, "secret") self.assertEqual(self.ref_private, key)
def test_export_private_pem_encrypted(self): encoded = self.ref_private._export_private_pem(passphrase=b"secret") # This should prove that the output is password-protected self.assertRaises(ValueError, ECC.import_key, encoded) assert "EC PRIVATE KEY" in encoded decoded = ECC.import_key(encoded, "secret") self.assertEqual(self.ref_private, decoded) # --- encoded = self.ref_private.export_key(format="PEM", passphrase="secret", use_pkcs8=False) decoded = ECC.import_key(encoded, "secret") self.assertEqual(self.ref_private, decoded)
def test_export_private_pkcs8_and_pem_2(self): # PKCS8 inside PEM with PKCS8 encryption encoded = self.ref_private._export_private_encrypted_pkcs8_in_clear_pem("secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") # This should prove that the output is password-protected self.assertRaises(ValueError, ECC.import_key, encoded) assert "ENCRYPTED PRIVATE KEY" in encoded decoded = ECC.import_key(encoded, "secret") self.assertEqual(self.ref_private, decoded) # --- encoded = self.ref_private.export_key(format="PEM", passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") decoded = ECC.import_key(encoded, "secret") self.assertEqual(self.ref_private, decoded)
def test_import_private_der(self): key_file = load_file("ecc_p384_private.der") key = ECC._import_private_der(key_file, None) self.assertEqual(self.ref_private, key) key = ECC._import_der(key_file, None) self.assertEqual(self.ref_private, key) key = ECC.import_key(key_file) self.assertEqual(self.ref_private, key)
def test_import_public_der(self): key_file = load_file("ecc_p521_public.der") key = ECC._import_subjectPublicKeyInfo(key_file) self.assertEqual(self.ref_public, key) key = ECC._import_der(key_file, None) self.assertEqual(self.ref_public, key) key = ECC.import_key(key_file) self.assertEqual(self.ref_public, key)
def test_compressed_curve(self): # Compressed P-256 curve (Y-point is even) pem1 = """-----BEGIN EC PRIVATE KEY----- MFcCAQEEIHTuc09jC51xXomV6MVCDN+DpAAvSmaJWZPTEHM6D5H1oAoGCCqGSM49 AwEHoSQDIgACWFuGbHe8yJ43rir7PMTE9w8vHz0BSpXHq90Xi7/s+a0= -----END EC PRIVATE KEY-----""" # Compressed P-256 curve (Y-point is odd) pem2 = """-----BEGIN EC PRIVATE KEY----- MFcCAQEEIFggiPN9SQP+FAPTCPp08fRUz7rHp2qNBRcBJ1DXhb3ZoAoGCCqGSM49 AwEHoSQDIgADLpph1trTIlVfa8NJvlMUPyWvL+wP+pW3BJITUL/wj9A= -----END EC PRIVATE KEY-----""" key1 = ECC.import_key(pem1) low16 = int(key1.pointQ.y % 65536) self.assertEqual(low16, 0xA6FC) key2 = ECC.import_key(pem2) low16 = int(key2.pointQ.y % 65536) self.assertEqual(low16, 0x6E57)
def test_cert_sign(): cert = load() assert cert['sign'] is not None pub_key = ECC.import_key(cert['public_key']) sign = bytes.fromhex(cert['sign']) verifier = DSS.new(pub_key, 'fips-186-3') hash_value = SHA256.new((cert['student_id'] + cert['is_success'] + str(cert['week'])).encode('utf-8')) try: verifier.verify(hash_value, sign) except: assert False
def test_export_private_pkcs8_and_pem_2(self): # PKCS8 inside PEM with PKCS8 encryption encoded = self.ref_private._export_private_encrypted_pkcs8_in_clear_pem( "secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") # This should prove that the output is password-protected self.assertRaises(ValueError, ECC.import_key, encoded) assert "ENCRYPTED PRIVATE KEY" in encoded decoded = ECC.import_key(encoded, "secret") self.assertEqual(self.ref_private, decoded) # --- encoded = self.ref_private.export_key( format="PEM", passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") decoded = ECC.import_key(encoded, "secret") self.assertEqual(self.ref_private, decoded)
def decrypt(_sk_dict, ctx): """ @sk_dict (dict): a dictionary of id->sk, it will try from the "first" element via (sk_dict.pop()) and try to decrypt and if fails will use the next one. Will fail if none of the id belong to the ctx @ctx (byte string): decrypts the ciphertext string """ # Don't change the input dictionary sk_dict = {k: v for k, v in _sk_dict.items()} # parse the ctx l_unsigned_int = struct.calcsize('<I') n_pk, ctx = struct.unpack('<I', ctx[:l_unsigned_int])[0], ctx[l_unsigned_int:] # get the pkctxs pkctx_dict = {ctx[i:i+4]: ctx[i+4:i+36] \ for i in range(0, n_pk*36, 36)} ctx = ctx[n_pk * 36:] serialized_random_point, ctx = ctx[:170], ctx[170:] nonce, tag, ctx = ctx[:16], ctx[16:32], ctx[32:] rand_point = ECC.import_key(serialized_random_point) def _decrypt_w_one_sk(sk, pkctx): assert isinstance(sk, ECC.EccKey) new_point = rand_point.pointQ * sk.d ki = hash256(str(new_point.x), str(new_point.y)) return aes1block(ki, pkctx, op='decrypt') msg = '' failed_to_decrypt = True # For debugging ctx_sk_ids = pkctx_dict.keys() give_sk_ids = [hash256(unicode(_id))[:4] for _id in sk_dict.keys()] # End debugging for _id, sk in sk_dict.items(): h_id = hash256(unicode(_id))[:4] if h_id not in pkctx_dict: continue aes_k = _decrypt_w_one_sk(sk, pkctx_dict[h_id]) try: msg = AES.new(key=aes_k, mode=AES.MODE_EAX, nonce=nonce)\ .decrypt_and_verify(ctx, tag) failed_to_decrypt = False break except (KeyError, ValueError) as e: print("Wrong key with id: {} and/or the ciphertext has been " "tampered".format(_id)) if failed_to_decrypt: raise KeyError("None of the secret keys ({}) could decrypt the "\ "ciphertext with keys=({}) (count={})".format( ctx_sk_ids, give_sk_ids, n_pk) ) return msg
def test_compressed_curve(self): # Compressed P-256 curve (Y-point is even) pem1 = """-----BEGIN EC PRIVATE KEY----- MFcCAQEEIHTuc09jC51xXomV6MVCDN+DpAAvSmaJWZPTEHM6D5H1oAoGCCqGSM49 AwEHoSQDIgACWFuGbHe8yJ43rir7PMTE9w8vHz0BSpXHq90Xi7/s+a0= -----END EC PRIVATE KEY-----""" # Compressed P-256 curve (Y-point is odd) pem2 = """-----BEGIN EC PRIVATE KEY----- MFcCAQEEIFggiPN9SQP+FAPTCPp08fRUz7rHp2qNBRcBJ1DXhb3ZoAoGCCqGSM49 AwEHoSQDIgADLpph1trTIlVfa8NJvlMUPyWvL+wP+pW3BJITUL/wj9A= -----END EC PRIVATE KEY-----""" key1 = ECC.import_key(pem1) low16 = int(key1.pointQ.y % 65536) self.assertEqual(low16, 0xA6FC) key2 = ECC.import_key(pem2) low16 = int(key2.pointQ.y % 65536) self.assertEqual(low16, 0x6E57)
def validate_private_key(ssh_private_key_data): try: RSA.import_key(from_base64(ssh_private_key_data)) return except ValueError: try: ECC.import_key(from_base64(ssh_private_key_data)) return except ValueError: try: DSA.import_key(from_base64(ssh_private_key_data)) return except ValueError: try: key_obj = io.StringIO( from_base64(ssh_private_key_data).decode('utf-8')) Ed25519Key(file_obj=key_obj) return except SSHException as ex: raise InvalidArgumentValueError( consts.SSH_PRIVATE_KEY_ERROR, consts.SSH_PRIVATE_KEY_HELP) from ex
def add_public_key(author: Union[AccountId, str], account: Union[AccountId, str], key: Union[str, ECC.EccKey], server: Server): """Add public key to account, with authorization from author""" author = _get_account(author, server) account = _get_account(account, server) _assert_authorized(author, account) if not isinstance(key, ECC.EccKey): try: key = ECC.import_key(key) except: raise ValueCommandException(key) server.add_public_key(account, key)
def __init__(self, buffer=None, key=None): if buffer: self.key = ECC.import_key(buffer) if self.key.curve == 'SECP160R1': self.curve_id = ECDSALowPrivateKey.SECP160R1 else: raise Exception("Unsupported curve") elif key: self.key = key if self.key.curve == 'SECP160R1': self.curve_id = ECDSALowPrivateKey.SECP160R1 else: raise Exception("Unsupported curve")
def sign_pop(self, session_dict): session_id = session_dict["pub_str"].strip() pop_token = session_dict["pop"]["token"].strip() view_key = session_dict["pop"]["view_key"].strip() string_to_sign = session_id + pop_token + view_key key = ECC.import_key(session_dict["priv_str"]) signature = self.generate_signature(key, string_to_sign) return { "Session-Id": session_id, "Pop-Token": pop_token, "View-Key": view_key, "Pop-Signature": signature }
def verifyticket(self, groupid, objectid, pubaddr, sign): sign = base64.b64decode(bytes(sign, encoding='utf-8')) signmsg = objectid + groupid + pubaddr #h=keccak.new(digest_bits=512) #h.update(str.encode(signmsg)) h = SHA256.new(str.encode(signmsg)) key = ECC.import_key(open("p" + groupid + '.pem', 'rt').read()) verifier = DSS.new(key, 'fips-186-3') try: verifier.verify(h, sign) return True except ValueError: return False
def check_keyfile_and_fetch_aes_key(root_dir, pub_name, priv_name, given_s): # checking the thing pub_key_file = open(pub_name, "r") sub = pub_key_file.readline() sub = sub[:-1] pb_s_type = pub_key_file.readline() pb_key = pub_key_file.read() pub_key_file.close() if(given_s != sub): print('Error: subject not correct') exit(1) priv_key_file = open(priv_name, "r") pr_sub = priv_key_file.readline() pr_s_type = priv_key_file.readline() pr_key = priv_key_file.read() priv_key_file.close() temp_f_name = os.path.join(root_dir, 'keyfile.sig') sig_file = open(temp_f_name, "rb") true_sig = sig_file.read() sig_file.close() temp_f_name = os.path.join(root_dir, 'keyfile') aes_file = open(temp_f_name, "rb") cipher_aes = aes_file.read() aes_file.close() ec_key = ECC.import_key(pb_key) temp_hash = SHA256.new(cipher_aes) verifier = DSS.new(ec_key, 'fips-186-3') try: verifier.verify(temp_hash, true_sig) except ValueError: print("The message is not authentic.") rsa_key = RSA.importKey(pr_key) cipher = PKCS1_OAEP.new(rsa_key) aes_key = cipher.decrypt(cipher_aes) # delete keyfile and keyfile.sig temp_f_name = os.path.join(root_dir, 'keyfile') os.remove(temp_f_name) temp_f_name = os.path.join(root_dir, 'keyfile.sig') os.remove(temp_f_name) return(aes_key)
def process_add_public_key(author: AccountId, message: str, server: Server, **kwargs): """Processes a message that requests for a public key to be associated with an account.""" account = assert_is_account(author, server) pem = '\n'.join(line for line in message.split('\n')[1:] if line != '' and not line.isspace()) try: key = ECC.import_key(pem) except Exception as e: raise CommandException( "Incorrectly formatted key. Inner error message: %s." % str(e)) server.add_public_key(account, key) return 'Public key added successfully.'
def sign(message, key_storage='privatekey.pem'): # load the private key for signing: f = open(key_storage, 'rt') private_key = ECC.import_key(f.read()) # hash the message h = hash(message) # sign with the private key signer = DSS.new(private_key, 'deterministic-rfc6979') signature = signer.sign(h) # reurn the signature return signature
def _validate_private_key(ssh_private_key_data): try: RSA.import_key(_from_base64(ssh_private_key_data)) return except ValueError: try: ECC.import_key(_from_base64(ssh_private_key_data)) return except ValueError: try: DSA.import_key(_from_base64(ssh_private_key_data)) return except ValueError: try: key_obj = io.StringIO( _from_base64(ssh_private_key_data).decode('utf-8')) Ed25519Key(file_obj=key_obj) return except SSHException: raise InvalidArgumentValueError( 'Error! --ssh-private-key provided in invalid format', 'Verify the key provided is a valid PEM-formatted key of type RSA, ECC, DSA, or Ed25519' )
def sign(self, private_key, payload): """ Hashes and signs the given payload with given private key. :param private_key: Private key of the signer in the string format. :param payload: JSON of the data to be signed. :return signature: signature in binary string format.""" private_key = b64decode(private_key).decode() h = self.__hash(payload) # Hash the payload signer = DSS.new(ECC.import_key(private_key), 'fips-186-3') # Get the signature object signature = signer.sign(h) # Sign the hash signature = b64encode(signature).decode('utf-8') logging.debug('Cryptohelper signed.') return signature
def verify_advertisement(msg, signature): print(msg, signature) print(type(msg), type(signature)) signature = bytes.fromhex(signature) key_str = json.loads(msg)['key'] hidden_addr = json.loads(msg)['hidden_addr'] key = ECC.import_key(key_str) verifier = DSS.new(key, 'fips-186-3') h = SHA256.new(msg.encode('utf8')) print(h.hexdigest()) try: verifier.verify(h, signature) return True, {"proxy_id": key_str, "hidden_address": hidden_addr} except ValueError: return False, {}
def test_ecc_asymmetric_key_generation(): with pytest.raises(ValueError, match="Unexisting ECC curve"): wacryptolib.key_generation.generate_asymmetric_keypair( key_type="ECC_DSS", curve="unexisting") for curve in (None, "p384"): extra_parameters = dict(curve=curve) if curve else {} keypair = wacryptolib.key_generation.generate_asymmetric_keypair( key_type="ECC_DSS", **extra_parameters) assert isinstance(keypair["private_key"], bytes), keypair assert isinstance(keypair["public_key"], bytes), keypair key = ECC.import_key(keypair["private_key"]) assert isinstance(key, ECC.EccKey)
def key_matrix_generator_Bob(public_key,array_of_images): """Key Matrix Generator""" key=ECC.import_key(public_key) #importing private key from Alice Q=key.pointQ P=ECC.EccPoint(x=key._curve.Gx,y=key._curve.Gy, curve='P-256') n=32 k_b = (random.randrange(2**(n-1)+1, 2**n - 1) ) k_c = (random.randrange(2**(n-1)+1, 2**n - 1)) ##note call the proper definition, R=k_b*P S=k_c*P K_0 = k_b*Q L = k_c*Q K_M=key_matrix_generator(K_0,L,array_of_images) # np.savetxt("Matrix.txt",(K_M)) return K_M,R,S
def get_private_key(): """ Set the private key from a file or by creating a new one :return: ECC private key object """ ensure_data_dir() # ensure directory exists try: # get existing private key key = ECC.import_key(open(_PRIVATE_KEY_PATH, 'rt').read()) except FileNotFoundError: # create public key key = ECC.generate(curve='P-256') # write private key to file file = open(_PRIVATE_KEY_PATH, 'wt') file.write(key.export_key(format='PEM')) file.close() return key
def sign(message, private_key_directory): """Function that sign data with ECDSA algorithm Args: message (string): data private_key_directory (private_key): directory to PEM file Returns: Object: Signature """ private_key = ECC.import_key(open(private_key_directory).read()) h = SHA256.new(message.encode()) signer = DSS.new(private_key, 'fips-186-3') signature = signer.sign(h) return signature
def check(self, signature: int): # Convert back to bytes sig = Conversion.IP2OS(signature) # Verifier setup ecc = ECC.import_key(self.pubk) verifier = DSS.new(ecc, 'fips-186-3') new_hash = SHA256.new(bytes.fromhex(self.y)) # We need to verify the signature on the hash. The verifier throws an exception if it doesn't verify. try: verifier.verify(new_hash, sig) return True except Exception as e: print(str(e), file=sys.stderr) return False
def test_export_private_pkcs8_encrypted(self): encoded = self.ref_private._export_pkcs8(passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") # This should prove that the output is password-protected self.assertRaises(ValueError, ECC._import_pkcs8, encoded, None) decoded = ECC._import_pkcs8(encoded, "secret") self.assertEqual(self.ref_private, decoded) # --- encoded = self.ref_private.export_key(format="DER", passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") decoded = ECC.import_key(encoded, "secret") self.assertEqual(self.ref_private, decoded)
def __init__(self, buffer=None, key=None): if buffer: self.key = ECC.import_key(buffer) if self.key.curve == 'NIST P-256': self.curve_id = ECDSAPrivateKey.NIST_P_256 elif self.key.curve == 'NIST P-384': self.curve_id = ECDSAPrivateKey.NIST_P_384 else: raise Exception("Unsupported curve") elif key: self.key = key if self.key.curve == 'NIST P-256': self.curve_id = ECDSAPrivateKey.NIST_P_256 elif self.key.curve == 'NIST P-384': self.curve_id = ECDSAPrivateKey.NIST_P_384 else: raise Exception("Unsupported curve")
def verify_transaction_signature(self): # Check if the transaction signature is valid # i.e. does the signature match the Transaction object. # Note: This might not make too much sense given the way we # create transactions in this tutorial. # But in case we get transaction data # from a remote point, this is important! public_key = ECC.import_key(binascii.unhexlify(self.sender)) verifier = DSS.new(public_key, 'fips-186-3') h = SHA256.new(str(self.odict_transaction()).encode('utf8')) try: verifier.verify(h, binascii.unhexlify(self.signature)) return (True) # In case the signature is no authentic, the verifier throws a ValueError except ValueError: return (False)
def ecc_sign(self, private_key: Union[ECC.EccKey, bytes], data: bytes, algorithm: str = None) -> bytes: """Sign data using (EC)DSA. :param private_key: ECC private key, either as EccKey or bytes :param data: Data to sign :param algorithm: Hash algorithm, if None the hash length is determined from ECC curve size :return: Signature, r and s coordinates as bytes """ key = private_key if isinstance( private_key, ECC.EccKey) else ECC.import_key(private_key) hash_name = algorithm or f"sha{key.pointQ.size_in_bits()}" hasher = self._get_algorithm(name=hash_name, data=data) signer = DSS.new(key, mode="deterministic-rfc6979") return signer.sign(hasher)
def verify_transaction_signature(self): if self.transaction_type == 1: return wallet = BlockChain().get_output_from_input(self.inputs[0]).wallet pubkey = ECC.import_key(bytes.fromhex(wallet)) verifier = DSS.new(pubkey, "fips-186-3") signature = self.signature self.signature = 0 hash_ = SHA256.new(self.serialize()) self.signature = signature try: verifier.verify(hash_, signature.to_bytes(64, "little")) except ValueError as check_fail: raise SecretError("Invalid transaction signature")
def test_export_private_pkcs8_encrypted(self): encoded = ref_private._export_pkcs8(passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") # This should prove that the output is password-protected self.assertRaises(ValueError, ECC._import_pkcs8, encoded, None) decoded = ECC._import_pkcs8(encoded, "secret") self.assertEqual(ref_private, decoded) # --- encoded = ref_private.export_key(format="DER", passphrase="secret", protection="PBKDF2WithHMAC-SHA1AndAES128-CBC") decoded = ECC.import_key(encoded, "secret") self.assertEqual(ref_private, decoded)
async def verifySignature(signature, publicKey, data): data = data.copy() data.pop("signature") data = json.dumps(data) publicKey = publicKey.split(" ") publicKey = "-----BEGIN PUBLIC KEY-----\n" + publicKey[ 0] + "\n" + publicKey[1] + "\n-----END PUBLIC KEY-----" publicKey = ECC.import_key(publicKey) signature = (int(signature, 16)).to_bytes(64, byteorder="little") data = SHA256.new(data.encode("utf-8")) verifier = DSS.new(publicKey, "fips-186-3") try: verifier.verify(data, signature) return True except ValueError: return False
def generate_keypair(self,private_key_str): # If this is a 'new' wallet, i.e. no private_key_str has been given to the constructor # --> Create a private key if private_key_str is None: # Generate the private key (in here the randomness takes place) private_key = ECC.generate(curve='P-256') else: # In case this is a wallet for a specific private_key # read the private key in string format. # binascii.unhexlify(x) converts x which is in hexadecimal format into a binary format private_key = ECC.import_key(binascii.unhexlify(private_key_str)) # Returns a dictionary with private and public key keypair = { 'private_key': binascii.hexlify(private_key.export_key(format='DER')).decode('utf8'), 'public_key': binascii.hexlify(private_key.public_key().export_key(format='DER')).decode('utf8') } return keypair
def verify(self): try: output = BlockChain().get_output_from_input(self) pubkey = ECC.import_key(bytes.fromhex(output.wallet)) except Exception as error: raise InvalidOutputReferenceError from error verifier = DSS.new(pubkey, "fips-186-3") # privkey = ECC.import_key(key) # signer = DSS.new(privkey, "fips-186-3") hash_ = SHA256.new(output.serialize()) try: verifier.verify(hash_, self.signature.to_bytes(64, "little")) except ValueError as check_fail: raise SecretError from check_fail
def get_public_key(output=None): """ Get the public key from a file or by creating a new one :param output: can equal 'string' if the public key needs to be a string :return: string or ECC object representing the public key """ ensure_data_dir() # ensure directory exists private_key = get_private_key() try: # get existing public key key = ECC.import_key(open(_PUBLIC_KEY_PATH).read()) except FileNotFoundError: # create public key from private key # write public key to file key = private_key.public_key() # plain text file = open(_PUBLIC_KEY_PATH, 'wt') file.write(key.export_key(format='PEM')) file.close() # return public key as string or ECC object return key.export_key(format='OpenSSH')
def convert_key(key_bytes): key = ECC.import_key(key_bytes).public_key() assert key.curve == 'NIST P-256' px_bytes = list(reversed(key._point.x.to_bytes(32))) py_bytes = list(reversed(key._point.y.to_bytes(32))) def chunked(l, chunk_len=8): for i in range(0, len(l), chunk_len): yield l[i:i + chunk_len] def join_hex(data): return ', '.join(f'0x{b:02x}' for b in data) def make_array(l): return '\n'.join(f'BYTES_TO_T_UINT_8( {join_hex(chunk)} ),' for chunk in chunked(l, 8)) return f'''
def add_tests(self, filename): comps = "Crypto.SelfTest.Signature.test_vectors.wycheproof".split(".") with open(pycryptodome_filename(comps, filename), "rt") as file_in: tv_tree = json.load(file_in) for group in tv_tree['testGroups']: try: key = ECC.import_key(group['keyPem']) except ValueError: continue hash_name = group['sha'] if hash_name == "SHA-512": hash_module = SHA512 elif hash_name == "SHA-384": hash_module = SHA384 elif hash_name == "SHA-256": hash_module = SHA256 elif hash_name == "SHA-224": hash_module = SHA224 elif hash_name == "SHA-1": hash_module = SHA1 else: assert False assert group['type'] == "ECDSAVer" from collections import namedtuple TestVector = namedtuple('TestVector', 'id comment msg sig key hash_module valid warning') for test in group['tests']: tv = TestVector( test['tcId'], test['comment'], unhexlify(test['msg']), unhexlify(test['sig']), key, hash_module, test['result'] != "invalid", test['result'] == "acceptable" ) self.tv.append(tv)
def deserialize_pk(pk_s): if isinstance(pk_s, (bytes, basestring, unicode)): return ECC.import_key(bytes(pk_s)) else: return pk_s
def test_import_private_pem(self): key_file = load_file("ecc_p521_private.pem") key = ECC.import_key(key_file) self.assertEqual(self.ref_private, key)
def test_import_public_pem(self): key_file = load_file("ecc_p256_public.pem") key = ECC.import_key(key_file) self.assertEqual(ref_public, key)
def import_key(extern_key, passphrase=None): return ECC.import_key(extern_key, passphrase)
def test_import_private_pem_with_ecparams(self): if sys.version_info[:2] == (2, 6): return key_file = load_file("ecc_p256_private_ecparams.pem") key = ECC.import_key(key_file)
def test_import_private_pkcs8_encrypted_2(self): key_file = load_file("ecc_p384_private_p8.pem") key = ECC.import_key(key_file, "secret") self.assertEqual(self.ref_private, key)
def test_import_private_pkcs8_in_pem_clear(self): key_file = load_file("ecc_p521_private_p8_clear.pem") key = ECC.import_key(key_file) self.assertEqual(self.ref_private, key)
def test_import_x509_pem(self): key_file = load_file("ecc_p521_x509.pem") key = ECC.import_key(key_file) self.assertEqual(self.ref_public, key)