def test_valid_signed_message(self, public_key, signed, message, signature): key = VerifyKey( public_key, encoder=HexEncoder, ) assert binascii.hexlify(key.verify(signed, encoder=HexEncoder), ) == message assert binascii.hexlify( key.verify(message, signature, encoder=HexEncoder), ) == message
def update_request_msg( msg: DeleteRequestMessage, node: AbstractNode, verify_key: VerifyKey, ) -> DeleteRequestResponse: # Get Payload Content request_id = msg.content.get("request_id", None) status = msg.content.get("status", None) current_user_id = msg.content.get("current_user", None) users = node.users if not current_user_id: current_user_id = users.first(verify_key=verify_key.encode( encoder=HexEncoder).decode("utf-8")).id # Check if status field is empty missing_paramaters = not status if missing_paramaters: raise MissingRequestKeyError( message="Invalid request payload, empty fields (status)!") _req = node.data_requests.first(id=request_id) if not _req: raise RequestError if status not in ["accepted", "denied"]: raise InvalidParameterValueError( message='Request status should be either "accepted" or "denied"') _can_triage_request = node.users.can_triage_requests( user_id=current_user_id) _current_user_key = verify_key.encode(encoder=HexEncoder).decode("utf-8") _req_owner = _current_user_key == _req.verify_key if status == "accepted" and _can_triage_request: tmp_obj = node.store[UID.from_string(_req.object_id)] tmp_obj.read_permissions[VerifyKey(_req.verify_key.encode("utf-8"), encoder=HexEncoder)] = _req.id node.store[UID.from_string(_req.object_id)] = tmp_obj node.data_requests.set(request_id=_req.id, status=status) elif status == "denied" and (_can_triage_request or _req_owner): node.data_requests.set(request_id=_req.id, status=status) else: raise AuthorizationError( "You're not allowed to update Request information!") return DeleteRequestResponse( address=msg.reply_to, status_code=200, content={"msg": "Request Updated!"}, )
def on_authenticate_ok(principal): self.log.info('{klass}.hello(realm="{realm}", details={details}) -> on_authenticate_ok(principal={principal})', klass=self.__class__.__name__, realm=realm, details=details, principal=principal) error = self._assign_principal(principal) if error: return error self._verify_key = VerifyKey(principal['pubkey'], encoder=nacl.encoding.HexEncoder) extra = self._compute_challenge(channel_binding) return types.Challenge(self._authmethod, extra)
def __addressToPk(cls, address): ''' Transform the stellar address (encoded ed25519 public key) to the coresponding curve25519 public key. Args: address: This is your Stellar address starting with letter 'G'. Returns: curve25519 public key as byte array. ''' return VerifyKey(decode_check('account', address)).to_curve25519_public_key()._public_key
def __init__(self, app: "FastAPI", *, client_public_key: str): """Initialize middleware Args: app (FastAPI): A valid, initialized FastAPI object client_public_key (str): a valid client public key """ super().__init__(app) self._client_public_key = client_public_key logger.info(f"pub: {self._client_public_key}") self._verification_key = VerifyKey( bytes.fromhex(self._client_public_key))
def genkeys(sk_hex): sk = SigningKey(seed=bytes.fromhex(sk_hex)) vk = sk.verify_key.encode().hex() public_key = VerifyKey(bytes.fromhex(vk)).to_curve25519_public_key()._public_key private_key = crypto_sign_ed25519_sk_to_curve25519(sk._signing_key) return { 'sk': sk_hex, 'vk': vk, 'public_key': public_key.hex(), 'private_key': encode(private_key), 'curve_key': encode(public_key) }
def make_verifier(key: str) -> VerifyKey: """ Create a NaCL verifier. args: key (str): A public key in minisign format base64(<signature_algorithm> || <key_id> || <public_key>) returns: nacl.signing.VerifyKey: a nacl verifykey object """ decoded = b64decode(key)[10:] return VerifyKey(decoded)
def test_legacy_closed_ns(omq, random_sn, sk, exclude): # For legacy closed groups the secret key is generated but then immediately discarded; it's only # used to generate a primary key storage address: swarm = ss.get_swarm(omq, random_sn, sk) sn = ss.random_swarm_members(swarm, 1, exclude)[0] conn = omq.connect_remote(sn_address(sn)) ts = int(time.time() * 1000) ttl = 86400000 exp = ts + ttl # namespace -10 is a special, no-auth namespace for legacy closed group messages. sclosed = omq.request_future(conn, 'storage.store', [json.dumps({ "pubkey": '05' + sk.verify_key.encode().hex(), "timestamp": ts, "ttl": ttl, "namespace": -10, "data": base64.b64encode("blah blah".encode()).decode()})]) sclosed = json.loads(sclosed.get()[0]) hash = blake2b("{}{}".format(ts, exp).encode() + b'\x05' + sk.verify_key.encode() + b'-10' + b'blah blah', encoder=Base64Encoder).decode().rstrip('=') assert len(sclosed["swarm"]) == len(swarm['snodes']) edkeys = {x['pubkey_ed25519'] for x in swarm['snodes']} for k, v in sclosed['swarm'].items(): assert k in edkeys assert hash == v['hash'] edpk = VerifyKey(k, encoder=HexEncoder) edpk.verify(v['hash'].encode(), base64.b64decode(v['signature'])) # NB: assumes the test machine is reasonably time synced assert(ts - 30000 <= sclosed['t'] <= ts + 30000) # Now retrieve it: this is the only namespace we can access without authentication r = omq.request_future(conn, 'storage.retrieve', [json.dumps({ "pubkey": '05' + sk.verify_key.encode().hex(), "namespace": -10, }).encode()]) r = r.get() assert len(r) == 1 r = json.loads(r[0]) assert len(r['messages']) == 1 msg = r['messages'][0] assert base64.b64decode(msg['data']) == b'blah blah' assert msg['timestamp'] == ts assert msg['expiration'] == exp assert msg['hash'] == hash
def _run_initial_setup() -> None: config = read_config() signing_key: Optional[SigningKey] = config.signing_key if not signing_key or not ask("Keep previous secret key", default=True): signing_key = SigningKey.generate() config.signing_key = signing_key write_config(config) verify_key = signing_key.verify_key nickname: Optional[str] = config.initial_setup_nickname if not nickname or not ask(f"Keep previous nickname [{nickname}]", default=True): default_nickname = os.environ.get("USER") or _random_name() nickname = ( input(f"Nickname [default: {default_nickname}]: ") or default_nickname ) config.initial_setup_nickname = nickname write_config(config) signed_nickname = sign_with_magic(b"NAME", signing_key, nickname.encode("utf-8")) vouch_data = verify_key.encode() + signed_nickname vouch_text = base64.b64encode(vouch_data).decode("utf-8") print("Ask someone to run the following command:") print(f"./pah.py vouch {vouch_text}") print() print("They should give you a token back in return. Paste that here:") inp = input().strip() try: token = base64.b64decode(inp.encode("utf-8")) data = SealedBox(signing_key.to_curve25519_private_key()).decrypt(token) config.server_address = data[32:].decode("utf-8") config.server_verify_key = VerifyKey(data[:32]) config.initial_setup_nickname = None except Exception: print("Invalid token!") sys.exit(1) print(f"Server: {config.server_address}") print("Testing connection...") port = connect(config) port.send_json({"method": "ping"}) port.receive_json() try: write_config(config) except Exception as e: print("Failed to write config:", e) sys.exit(1) print("permuter@home successfully set up!")
def _proto2object(proto: RequestMessage_PB) -> "RequestMessage": request_msg = RequestMessage( request_id=deserialize(blob=proto.request_id), name=proto.name, request_description=proto.request_description, address=deserialize(blob=proto.target_address), object_id=deserialize(blob=proto.object_id), owner_address=deserialize(blob=proto.owner_address), requester_verify_key=VerifyKey(proto.requester_verify_key), timeout_secs=proto.timeout_secs, ) request_msg.request_id = deserialize(blob=proto.request_id) return request_msg
def verify_signature(signature, message): verify_key_hex = os.environ["VERIFY_KEY"] key_bytes = binascii.unhexlify(verify_key_hex) verify_key = VerifyKey(key_bytes) try: verify_key.verify(signature.encode(), encoder=HexEncoder) signature_body = binascii.unhexlify(signature) if signature_body[(-1 * len(message)):].decode() != message: return False except Exception as e: print(str(e)) return False return True
def test_valid_signed_message(self, _seed, public_key, message, signature, signed): key = VerifyKey( public_key, encoder=HexEncoder, ) assert (binascii.hexlify(key.verify(signed, encoder=HexEncoder), ) == message) assert (binascii.hexlify( key.verify(message, HexEncoder.decode(signature), encoder=HexEncoder), ) == message)
def is_signature_valid(verify_key: hexstr, message: bytes, signature: hexstr) -> bool: try: verify_key_bytes = hex_to_bytes(verify_key) signature_bytes = hex_to_bytes(signature) except ValueError: return False try: VerifyKey(verify_key_bytes).verify(message, signature_bytes) except BadSignatureError: return False return True
def test_delete_all(omq, random_sn, sk, exclude): swarm = ss.get_swarm(omq, random_sn, sk) sns = ss.random_swarm_members(swarm, 2, exclude) conns = [omq.connect_remote(sn_address(sn)) for sn in sns] msgs = ss.store_n(omq, conns[0], sk, b"omg123", 5) my_ss_id = '05' + sk.verify_key.encode().hex() ts = int(time.time() * 1000) to_sign = "delete_all{}".format(ts).encode() sig = sk.sign(to_sign, encoder=Base64Encoder).signature.decode() params = json.dumps({ "pubkey": my_ss_id, "timestamp": ts, "signature": sig }).encode() resp = omq.request_future(conns[1], 'storage.delete_all', [params]).get() assert len(resp) == 1 r = json.loads(resp[0]) assert set( r['swarm'].keys()) == {x['pubkey_ed25519'] for x in swarm['snodes']} msg_hashes = sorted(m['hash'] for m in msgs) # signature of ( PUBKEY_HEX || TIMESTAMP || DELETEDHASH[0] || ... || DELETEDHASH[N] ) expected_signed = "".join((my_ss_id, str(ts), *msg_hashes)).encode() for k, v in r['swarm'].items(): assert v['deleted'] == msg_hashes edpk = VerifyKey(k, encoder=HexEncoder) edpk.verify(expected_signed, base64.b64decode(v['signature'])) r = omq.request_future(conns[0], 'storage.retrieve', [ json.dumps({ "pubkey": my_ss_id, "timestamp": ts, "signature": sk.sign(f"retrieve{ts}".encode(), encoder=Base64Encoder).signature.decode() }).encode() ]).get() assert len(r) == 1 r = json.loads(r[0]) assert not r['messages']
def verify(msg, sig, verifying_key): """ Verify a signature. :param bytes msg: message that was signed. :param bytes sig: signature to verify. :param bytes verifying_key: verifying key from generate_signature_keypair(). :returns: True or False whether the verification succeeds or fails. :rtype: boolean """ try: return msg == VerifyKey(verifying_key).verify(msg, sig) except BadSignatureError: return False
async def verifySignature(signature, publicKey, data): data = data.copy() data.pop("signature") data = json.dumps(data).encode() publicKey = publicKey[4:56] + "====" publicKey = base64.b32decode(publicKey.upper().encode()) verifier = VerifyKey(publicKey) signature = (int(signature, 16)).to_bytes(64, byteorder="little") try: verifier.verify(data, signature) return True except BadSignatureError: return False
def test_remote_feed(): public = b64decode('I/4cyN/jPBbDsikbHzAEvmaYlaJK33lW3UhWjNXjyrU=') feed = Feed(VerifyKey(public)) assert bytes(feed.public_key) == public assert feed.id == '@I/4cyN/jPBbDsikbHzAEvmaYlaJK33lW3UhWjNXjyrU=.ed25519' m1 = Message(feed, OrderedDict([('type', 'about'), ('about', feed.id), ('name', 'neo'), ('description', 'The Chosen One')]), 'foo', timestamp=1495706260190) with pytest.raises(NoPrivateKeyException): feed.sign(m1)
def is_signature_valid(account_id, signature, data: bytes) -> bool: """ Verify the signature of a message :param account_id: the account id signing the message :param signature: the signature of the message :param data: the message that has been signed :return: true if the signature for the message is valid, false otherwise """ try: id = hashing.decode(account_id) if isinstance(account_id, str) else account_id sg = hashing.decode(signature) if isinstance(signature, str) else signature VerifyKey(id).verify(data, sg) return True except Exception: return False
def verify_signature(signed, public): vk = VerifyKey(public) vk.verify(signed) child = Child( signed[0:64], signed[64:128], int.from_bytes(signed[128:144], 'little'), int.from_bytes(signed[144:160], 'little'), signed[160:192], signed[192:], ) if child.public != public: raise ValueError('embedded pubkey mismatch: {!r} != {!r}'.format( child.public, public)) return child
def __init__(self, kp): ''' Initialize the Whisper class using your Stellar. Args: kp: This is your Stellar keypair, as encoded by the stellar_base.keypair class. Returns: Instance of the object. ''' self.__kp = kp self.__sk = SigningKey(kp.raw_seed()).to_curve25519_private_key()._private_key self.__pk = VerifyKey(kp.raw_public_key()).to_curve25519_public_key()._public_key self.__address = kp.address().decode() self.__seed = kp.seed().decode()
def verify(self, message, signature, verification_key): """Verify that the signature using the verification key Args: message (bytes): The received message. signature (bytes): The recieved signature. verification_key (bytes): The verification key. Returns: bool: True if the verification succeeds. """ try: VerifyKey(verification_key).verify(message, signature) return True except BadSignatureError: return False
def verify_client_auth(self, data): assert len(data) == 112 a_bob = crypto_scalarmult(bytes(self.local_key.to_curve25519_private_key()), self.remote_ephemeral_key) box_secret = hashlib.sha256(self.application_key + self.shared_secret + a_bob).digest() self.hello = crypto_box_open_afternm(data, b'\x00' * 24, box_secret) signature, public_key = self.hello[:64], self.hello[64:] signed = self.application_key + bytes(self.local_key.verify_key) + self.shared_hash pkey = VerifyKey(public_key) # will raise an exception if verification fails pkey.verify(signed, signature) self.remote_pub_key = pkey b_alice = crypto_scalarmult(bytes(self.local_ephemeral_key), bytes(self.remote_pub_key.to_curve25519_public_key())) self.box_secret = hashlib.sha256(self.application_key + self.shared_secret + a_bob + b_alice).digest()[:32] return True
def test_signature(self, shared_datadir): json_raw = (shared_datadir / "version.json").read_text() version_data = json.loads(json_raw) sig = version_data["signature"] del version_data["signature"] data = json.dumps(version_data, sort_keys=True) version_data = bytes(data, "utf-8") jms_pub = (shared_datadir / "jms.pub").read_text() public_key = VerifyKey(jms_pub, UnpaddedBase64Encoder()) sig = UnpaddedBase64Encoder.decode(sig) public_key.verify(version_data, sig)
def __verifyTxPubKeyAndSig(self, tx: Transaction) -> bool: # each output in the input has the same public key, and that key can be used to verify the signature of the transaction if not tx.txInputs: return False senderPubKey: bytes = tx.txInputs[0].output.pubKey for txInput in tx.txInputs: if txInput.output.pubKey != senderPubKey: log.error("Node " + self.id + " :" + "Tx Verification Failed! Input pubKey is not unique") return False verifyKey = VerifyKey(senderPubKey, HexEncoder) try: verifyKey.verify(tx.sig.encode('utf-8'), encoder=HexEncoder) return True except BadSignatureError: log.error("Node " + self.id + " :" + "Tx Verification Failed! Signature verification failed") return False
def verify(self, data, signature, verify_key=""): """ data is the original data we have to verify with signature signature is Ed25519 64 bytes signature verify_key is the verify key, is not specified will use your own (the verify key is 32 bytes) """ if verify_key is None or verify_key == "": verify_key = self.verify_key elif j.data.types.bytes.check(verify_key): verify_key = VerifyKey(verify_key) try: verify_key.verify(data, signature) except BadSignatureError: return False return True
def verifyTxPubKeyAndSig(self, tx: Transaction): # each output in the input has the same public key, and that key can be used to verify the signature of the transaction if not tx.inputList: return False sender_PublicKey: bytes = tx.inputList[0].output.pubkey for Input in tx.inputList: if Input.output.pubkey != sender_PublicKey: logger.error("In Node " + str(self.id) + " :" + "Tx Verification Failed! Input pubkey is not unique") return False verifyKey = VerifyKey(sender_PublicKey, HexEncoder) try: verifyKey.verify(tx.sig.encode('utf-8'), encoder=HexEncoder) return True except BadSignatureError: logger.error("In Node " + str(self.id) + " :" + "Tx Verification Failed! Signature verification failed") return False
def sign_digest(self, digest: bytes, trust_set_key: bytes): # Create the subject subject = Subject() # Create a VerifyKey from the bytes key = VerifyKey(trust_set_key) # Handle trust set def on_trust_set(trust_set: TrustSet): # Create a TimeCertificateBuilder to handle this request builder = TimeCertificateBuilder(trust_set, key, digest) # Hook up the result to our subject builder.result.subscribe(subject.on_next, subject.on_error, subject.on_completed) # Prepare to handle signature request events def handle_sig_events(event: ProtocolEvent): if(event.type == ProtocolEvent.EVENT_RESPONDED): builder.add_signature(event.result) print("Signature received from peer") else: self.__print_event(event) # Iterate over the valid public keys for public_key in trust_set.valid_keys: # Request a signature self.protocol.request_signature(public_key, digest).subscribe(handle_sig_events) def handle_tsr_events(event: ProtocolEvent): if(event.type == ProtocolEvent.EVENT_RESPONDED): on_trust_set(event.result) else: self.__print_event(event) # Do we have the trust set? if(self.store.has_trust_set(key)): print("Trust set found locally") on_trust_set(self.store.get_trust_set(key)) else: self.protocol.request_trust_set(key).subscribe(handle_tsr_events) return subject
def add_participant(self, request, folder_name): """ Add a new participant to this folder with details from the JSON-encoded body. """ folder_service = self._global_service.get_folder_service(folder_name) body = request.content.read() participant = _load_json(body) required_keys = { "author", "personal_dmd", } required_author_keys = { "name", # not yet # "public_key_base32", } if set(participant.keys()) != required_keys: raise _InputError("Require input: {}".format(", ".join( sorted(required_keys)))) if set(participant["author"].keys()) != required_author_keys: raise _InputError("'author' requires: {}".format(", ".join( sorted(required_author_keys)))) author = create_author( participant["author"]["name"], # we don't yet properly track keys but need one # here .. this won't be correct, but we won't use # it .. following code still only looks at the # .name attribute # see https://github.com/LeastAuthority/magic-folder/issues/331 VerifyKey(os.urandom(32)), ) personal_dmd_cap = Capability.from_string(participant["personal_dmd"]) if not personal_dmd_cap.is_readonly_directory(): raise _InputError( "personal_dmd must be a read-only directory capability.") yield folder_service.add_participant(author, personal_dmd_cap) request.setResponseCode(http.CREATED) _application_json(request) returnValue(b"{}")
def verify_block(cls, block, difficulty=1, difficulty_mode=0): try: # reject if it does not meet the required difficulty if not cls.meets_difficulty(block['signature'], difficulty, difficulty_mode): return False # then verify the signature verify_key = VerifyKey(block['address']) if type( block['address']) == type('s') or type( block['address']) == type(b's') else block['address'] verify_key.verify( block['previous_block'] + block['nonce'] + block['body'], block['signature']) return True except nacl.exceptions.BadSignatureError: return False except KeyError: return False
def lambda_handler(event, context): print(json.dumps(event)) body = json.loads(event['body']) PUBLIC_KEY = os.getenv('DISCORD_PUBKEY') verify_key = VerifyKey(bytes.fromhex(PUBLIC_KEY)) try: signature = event["headers"]["x-signature-ed25519"] timestamp = event["headers"]["x-signature-timestamp"] str_body = event['body'] verify_key.verify(f'{timestamp}{str_body}'.encode(), bytes.fromhex(signature)) except BadSignatureError: print('bad signature error') return { 'statusCode': 401, 'body': json.dumps('invalid request signature') } except KeyError: print('cannot find keys') return { 'statusCode': 401, 'body': json.dumps('missing request signature') } print("body type is: {type}".format(**body)) if body['type'] == 1: print('found a ping. responding with "type": 1') return {'statusCode': 200, 'body': json.dumps({"type": 1})} # dummy response to everything if body['type'] == 2: print(json.dumps(body)) print('hey look a message. let\'s respond') return { 'statusCode': 200, 'body': json.dumps({ "type": 4, "data": { "content": f"<@{body['member']['user']['id']}> your request has been entered. Linking your accounts now..." } }) }