Python - How to generate a pair of keys using the pycryptodome library, without messing everthing up
NOTE: My English is not very good
I'm trying to make a "cryptocurrency", I was in the blockchain part, but, when I was making a little interface for my program, I was having a problem generating new public and private keys. I was having this problem using the rsa
. So figured out to change the library, and use a more popular one, the pycryptodome
library.
Ok, I was remaking my code with this new library, but, when I was generating new pairs of keys, I was having a problem with parameters in the transaction class I was having, here is the code of the class:
class Transaction():
def __init__(self, sender_public_key, recipient_public_key, sender_private_key, value):
self.sender_public_key = sender_public_key
self.recipient_public_key = recipient_public_key
self.sender_private_key = sender_private_key
self.value = value
def sign_transaction(self):
public_transaction = {'sender_public_key': self.sender_public_key,
'recipient_public_key' : self.recipient_public_key,
'value' : self.value
}
private_key = RSA.importKey(binascii.unhexlify(self.sender_private_key))
signer = PKCS1_v1_5.new(private_key)
h = SHA512.new(str(public_transaction)).encode('utf8')
signature = binascii.hexlify(signer.sign(h)).decode('ascii')
public_transaction['signature'] = signature
return public_transaction
And here is the code when generating new pair of keys:
def generate_public_and_private_key():
random_gen = Crypto.Random.new().read
private_key = RSA.generate(1024, random_gen)
public_key = private_key.public_key
return {['private_key']: binascii.hexlify(private_key.exportKey(format='DER')).decode('ascii'),
['public_key']: binascii.hexlify(public_key.exportKey(format='DER')).decode('ascii')
}
Basically, to sign the transaction, I needed to pass another parameter, that messed with all my code (this new parameter is something that the user wouldn't know). To explain better what this new parameter is, I recommend taking a look at this website: https://cryptobook.nakov.com/digital-signatures/rsa-sign-verify-examples
I'm going to leave my entire code here:
import binascii
from Crypto.PublicKey import RSA
import Crypto
from Crypto.Hash import SHA512
from Crypto.Signature import *
import time
from hashlib import sha512
import getpass
def generate_public_and_private_key():
random_gen = Crypto.Random.new().read
private_key = RSA.generate(1024, random_gen)
public_key = private_key.public_key
return {['private_key']: binascii.hexlify(private_key.exportKey(format='DER')).decode('ascii'),
['public_key']: binascii.hexlify(public_key.exportKey(format='DER')).decode('ascii')
}
class Blockchain():
def __init__(self):
self.chain = []
self.current_data = []
self.construct_genesis()
def construct_genesis(self):
self.construct_block()
def construct_block(self, prev_hash='0' * 64):
block = Block(data = self.current_data,
index = len(self.chain),
prev_hash = prev_hash)
self.current_data = []
self.chain.append(block)
return block
def add_transaction(self, transaction):
self.current_data.append(transaction)
return True
class Block():
def __init__(self, data, index, prev_hash):
self.data = data
self.index = index
self.prev_hash = prev_hash
self.mining()
def mining(self):
nonce = 0
while True:
block_string = "{}{}{}{}".format(self.index, self.prev_hash, self.data, str(nonce))
block_string_hashed = sha512(block_string.encode('ascii')).hexdigest()
if block_string_hashed.startswith("0" * 5):
proof_of_work = block_string_hashed
self.nonce = nonce
self.hash = block_string_hashed
self.timestamp = time.time()
return proof_of_work
nonce += 1
class Transaction():
def __init__(self, sender_public_key, recipient_public_key, sender_private_key, value):
self.sender_public_key = sender_public_key
self.recipient_public_key = recipient_public_key
self.sender_private_key = sender_private_key
self.value = value
def sign_transaction(self):
public_transaction = {'sender_public_key': self.sender_public_key,
'recipient_public_key' : self.recipient_public_key,
'value' : self.value
}
private_key = RSA.importKey(binascii.unhexlify(self.sender_private_key))
signer = PKCS1_v1_5.new(private_key)
h = SHA512.new(str(public_transaction)).encode('utf8')
signature = binascii.hexlify(signer.sign(h)).decode('ascii')
public_transaction['signature'] = signature
return public_transaction
def main():
blockchain = Blockchain()
print('-' * 30 + ' Welcome to the Cryptocoin! ' + "-" * 30)
while True:
time.sleep(1)
print('Choose between the options below')
time.sleep(1)
print()
print('[1]: Add a new transaction')
time.sleep(1)
print('[2]: Mine a block')
time.sleep(1)
print('[3]: Quit')
time.sleep(1)
while True:
print()
choice = int(getpass.getpass('Type: '))
if choice <=3 and choice > 0:
break
else:
print()
print("Invalid value! Answer only 1 or 2!")
if choice == 1:
print()
print("You choosed to add a new transaction.")
print()
time.sleep(1)
print("Do you have a pair of keys? Answer \"y\" or \"n\"")
time.sleep(1)
while True:
print()
answer = getpass.getpass('Type: ').replace(" ", "").lower()
if answer == "y" or answer == "n":
break
else:
print("Invalid value! Answer only \"y\" or \"n\"!")
if answer == "y":
print()
sender_private_key = getpass.getpass("Type your private key: ").replace(" ", "").encode()
print()
sender_public_key = getpass.getpass("Type your public key: ").replace(" ", "").encode()
print()
recipient_public_key = getpass.getpass("Type the public key of the person you want to transact: ").replace(" ", "").encode()
print()
value = int(input("Type the value of the transaction: "))
print()
transaction = Transaction(sender_public_key, recipient_public_key, sender_private_key, value)
public_transaction = transaction.sign_transaction()
blockchain.add_transaction(public_transaction)
time.sleep(1)
print('Trasaction successfully registered!')
if __name__ == '__main__':
sender_pair_of_keys = generate_public_and_private_key()
recipient_pair_of_keys = generate_public_and_private_key()
sender_public_key = sender_pair_of_keys['public_key']
sender_private_key = sender_pair_of_keys['private_key']
recipient_public_key = recipient_pair_of_keys['public_key']
print(f"Sender public key: {sender_public_key}")
print(f'Sender private key: {sender_private_key}')
print(f'Recipient public key: {recipient_public_key}')
main()
from Recent Questions - Stack Overflow https://ift.tt/3l1yrrk
https://ift.tt/eA8V8J
Comments
Post a Comment