From ae14376b13c7724e86db7e0687cd483b7ded3a2f Mon Sep 17 00:00:00 2001 From: kalzu Date: Thu, 29 Dec 2022 22:09:26 +0200 Subject: [PATCH] Now kraken-fetch.py has signatures both ways. Maybe adding ECDH to the messaging at some point. --- btc_tracker/kraken_fetch.py | 26 +++++++++++++++-------- letters/two-key-pairs.py | 41 +++++++++++++++++++++++++++++++++++++ python3-ecdsa-ecdh-tests.py | 8 ++++++++ 3 files changed, 66 insertions(+), 9 deletions(-) create mode 100755 letters/two-key-pairs.py create mode 100755 python3-ecdsa-ecdh-tests.py diff --git a/btc_tracker/kraken_fetch.py b/btc_tracker/kraken_fetch.py index d544bba..50a545e 100755 --- a/btc_tracker/kraken_fetch.py +++ b/btc_tracker/kraken_fetch.py @@ -1,9 +1,10 @@ #!/usr/bin/python3 import krakenex, math -import json, sqlite3, rsa +import json, sqlite3, binascii import requests, os, time import threading, ecdsa +from Cryptodome.Cipher import AES from hashlib import sha256 from flask import Flask, jsonify, request @@ -12,13 +13,16 @@ app = Flask(__name__) ## Add your public key here user_publickeys = { - "kalzu": 'f1debc13fb21fe0eee54525aa4f8aae5733b201c755edaa55f8893c90aa375b261a62eaa3110651ac5d7705d402581256a37508b0a1ca28bd919ea44710d9c88' + "user1": 'f1debc13fb21fe0eee54525aa4f8aae5733b201c755edaa55f8893c90aa375b261a62eaa3110651ac5d7705d402581256a37508b0a1ca28bd919ea44710d9c88' } -## Generate the RSA keys for this instance -print("Generating RSA keys for this instance... just wait a bit...") -(server_public_key, server_private_key) = rsa.newkeys(4096) -server_public_key_string = server_public_key.save_pkcs1().decode('utf-8') +## Generate the ECDSA keys for this instance +print("Generating ECDSA keys for this instance... just wait a bit...") +server_private_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) +server_public_key = server_private_key.get_verifying_key() +# We need the hexadecimal form for sharing over http/json +server_public_key_hex = binascii.hexlify(server_public_key.to_string()).decode('utf-8') + database_lock = threading.Lock() @@ -248,6 +252,7 @@ def check_auth(text, signature): try: vk.verify(sig_bytes, bytes(text, 'utf-8')) print('user is', key) + return True except ecdsa.BadSignatureError: return False @@ -284,24 +289,27 @@ def get_data(): updated_data = {"shasum": data_shasum} updated_data.update(data) data = updated_data + + # sign the response + signature = server_private_key.sign(json.dumps(data).encode('utf-8')) + signature_hex = binascii.hexlify(signature).decode('utf-8') + data['signature'] = signature_hex if query_pretty: response = json.dumps(data, indent=2, separators=(';\n', ' :')) else: response = json.dumps(data) - return response, 200, {'Content-Type': 'application/json'} @app.route('/serverkey') def give_serverkey(): - ## This endpoint also under Authentication? signature = request.headers.get('auth') get_url = request.url if not check_auth(get_url, signature): return 'Access denied! Check your keys, maybe.', 403 - return jsonify({'public_key': server_public_key_string}) + return jsonify({'public_key': server_public_key_hex}) if __name__ == '__main__': # Make sanity checks for the database diff --git a/letters/two-key-pairs.py b/letters/two-key-pairs.py new file mode 100755 index 0000000..8e4d91c --- /dev/null +++ b/letters/two-key-pairs.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 +import ecdsa +from cryptography.fernet import Fernet + +# Generate a signing key pair for the server +server_signing_private_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) +server_signing_public_key = server_signing_private_key.get_verifying_key() + +# Generate an encryption key pair for the server +server_ecdh = ecdsa.ECDH(curve=ecdsa.SECP256k1) +server_encryption_private_key = server_ecdh.generate_private_key() +server_encryption_public_key = server_ecdh.public_key(server_encryption_private_key) + + +# Generate a signing key pair for the client +client_signing_private_key = ecdsa.SigningKey.generate(curve=ecdsa.SECP256k1) +client_signing_public_key = client_signing_private_key.get_verifying_key() + +# Generate an encryption key pair for the client +client_ecdh = ecdsa.ECDH(curve=ecdsa.SECP256k1) +client_encryption_private_key = client_ecdh.generate_private_key() +client_encryption_public_key = client_encryption_private_key.public_key() + +# Exchange public keys between the server and the client +server_shared_secret = server_encryption_private_key.exchange(client_encryption_public_key) +client_shared_secret = client_encryption_private_key.exchange(server_encryption_public_key) + +# Use the shared secret to create a Fernet object for encrypting/decrypting messages +server_fernet = Fernet(server_shared_secret) +client_fernet = Fernet(client_shared_secret) + +# Sign and encrypt a message from the server to the client +message = "Hello, client!" +signed_message = server_signing_private_key.sign(message.encode()) +encrypted_message = server_fernet.encrypt(signed_message) + +# Verify and decrypt the message on the client side +verified_message = client_signing_public_key.verify(encrypted_message, signed_message) +decrypted_message = client_fernet.decrypt(verified_message) +print(decrypted_message) # "Hello, client!" + diff --git a/python3-ecdsa-ecdh-tests.py b/python3-ecdsa-ecdh-tests.py new file mode 100755 index 0000000..f0da4d3 --- /dev/null +++ b/python3-ecdsa-ecdh-tests.py @@ -0,0 +1,8 @@ +#!/usr/bin/python3 + +import ecdsa + +ecdh = ecdsa.ECDH(curve=ecdsa.SECP256k1) +private_key = ecdh.generate_private_key() + +print(str(private_key))