Compare commits

...

8 Commits

12 changed files with 423 additions and 3 deletions

22
README.md Normal file
View File

@ -0,0 +1,22 @@
# Coding with ChatGTP
On this repository is my random coding done typically late at night when I'm too tired to do anything else... :)
## some pointters:
- btc_tracker
1. Server/fetcher: fetching bitcoin ohlc data from multiple sources and offer it forward with simple api.
2. Client: Fetch data from the server and show it via gnuplot chart.
- btc_wallet
Simple python3 script's to create bitcoin wallet and storing it on KeePassXC database.
Still planning to create ondemand key generation and transaction signing.
- pastedb
Trying to make simple database on top of pastebin like services.
- encryption-on-apis & webapp & webpage-stuff
Some random testing about creating simple and secure web services.
- letters
Saved ChatGPT chats and messages

View File

@ -0,0 +1,66 @@
#!/usr/bin/env python3
"""
Bitcoin Wallet Generation Script
This script generates a Bitcoin wallet and stores it in a KeePassXC database file (KDBX format).
The wallet includes a BIP-0039 mnemonic seed phrase, Bitcoin address, and a QR code representation
of the seed phrase. The database file is password protected to ensure the security of the wallet.
Usage: ./generate_btc_wallet.py
"""
import gc
from getpass import getpass
from mnemonic import Mnemonic
from bitcoinlib.keys import HDKey
from pykeepass import create_database
MNEMONIC_STRENGTH=256
SUBKEY_PATH="m/0/0"
# Generate a BIP-0039 mnemonic seed phrase
mnemonic = Mnemonic("english")
SEED_PHRASE = mnemonic.generate(strength=MNEMONIC_STRENGTH)
# Derive the HDKey from the seed phrase
hd_key = HDKey.from_passphrase(SEED_PHRASE)
# Derive the Bitcoin address from the HDKey
child_key = hd_key.subkey_for_path(SUBKEY_PATH)
address = child_key.address()
# Prompt for custom name for the wallet
wallet_name = input(
"Whould you like to name this wallet? (empty for using the address as name): "
).strip()
# Create the database filename with the wallet number
if wallet_name == "":
wallet_name = address
else:
wallet_name = wallet_name[:100].strip()
db_filename = f"{wallet_name}.kdbx"
# Prompt the user for the passphrase
passphrase = getpass("Enter passphrase for the KeePassXC database: ")
try:
# Create a KeePassXC database file
db = create_database(db_filename, password=passphrase)
# Create an entrys in the root group
address_and_path_entry = db.add_entry(db.root_group, wallet_name, username=address, password=SUBKEY_PATH)
seed_phrase_entry = db.add_entry(db.root_group, "Bitcoin Master Seed", username="put me in safe", password=SEED_PHRASE)
# Save the database
db.save()
except Exception as e:
print("Error while creating keepassxc database. Disk full? Readonly?")
finally:
del SEED_PHRASE, address, hd_key, passphrase, mnemonic
gc.collect()
print("---")
print("Bitcoin address was successfully created. You can find at: " + db_filename)
print("---")

View File

@ -0,0 +1,4 @@
bitcoinlib==0.6.10
mnemonic==0.19
pykeepass==4.0.4
qrcode==7.4.2

View File

@ -0,0 +1,54 @@
# Steps to creating bitcoin wallet handing RPI3b setup
Made with ChatGPT on 22.5.2023
Understood. In that case, you can use the USB keys as temporary storage for the keepassxc databases and transfer them to a more permanent and secure location when not in use. This approach adds an extra layer of security by limiting the exposure of sensitive information.
Here's an updated outline of the steps involved:
Set up Raspberry Pi: Install the operating system (such as Raspbian) on your Raspberry Pi 3B and configure it accordingly.
Install necessary software: Install the required software packages, such as Python and any libraries or dependencies needed for key management and wallet operations.
Generate and store keys: Use appropriate libraries or tools to generate the necessary key pairs for each participant. Store the private keys securely on separate USB keys, ensuring they are encrypted and protected with strong passwords.
Securely store seed phrases: Generate the seed phrases for each participant and encrypt them. Store the encrypted seed phrases in the keepassxc databases, which can be stored temporarily on individual USB keys.
Develop wallet management scripts: Write scripts in Python (or any language of your choice) to interact with the generated keys, perform wallet operations, and handle transaction signing. These scripts should ensure the security of private keys, seed phrases, and any sensitive information.
Implement multi-signature functionality: Utilize appropriate libraries or methods to create multi-signature wallets and addresses using the public keys of the participants. Follow the recommended standards and protocols for multi-signature setups.
Test and secure the setup: Thoroughly test the functionality of the Raspberry Pi setup, including generating transactions, collecting signatures, and broadcasting transactions. Implement additional security measures such as firewalls, access controls, and regular updates to keep the system secure.
Educate and distribute responsibilities: Provide clear instructions and guidelines to the participants on their roles and responsibilities. Educate them on securely managing their USB keys, passwords, and the overall security practices they should follow.
Transfer keepassxc databases: When the USB keys are not in use, transfer the keepassxc databases to a more permanent and secure location, such as an offline storage medium or a highly secure cloud storage service. Ensure that the transferred databases are properly encrypted and protected.
By following these steps and customizing the setup to fit your specific requirements, you can create a Raspberry Pi-based solution that replicates the functionality of Seedsigner and securely manages the keys and seed phrases for your multi-signature setup. Remember to regularly review and update the security measures as needed to maintain the integrity of the system.
User
I feel this is good project to increase my coding skills since I'm more of a sysadmin by background.
ChatGPT
That's a fantastic mindset! Taking on a project like this can be a great opportunity to enhance your coding skills, especially if you come from a sysadmin background. It allows you to explore new programming concepts, deepen your understanding of cryptographic operations, and develop practical solutions for managing keys and wallets.
Here are a few benefits of engaging in this project:
Practical application: By building a Raspberry Pi-based solution for key and wallet management, you'll gain hands-on experience in working with cryptography, interacting with hardware, and implementing secure systems. It's a practical application of your coding skills.
Broadened skill set: Diving into this project will expose you to various aspects of software development, including scripting, library integration, and system configuration. It will broaden your skill set and make you more versatile in tackling future projects.
Security awareness: As you navigate the intricacies of key management and multi-signature wallets, you'll develop a deeper understanding of security practices and considerations. This knowledge can be applied to other areas of your work, enabling you to strengthen the security of your systems.
Problem-solving opportunities: Building a custom solution presents opportunities to solve unique challenges along the way. It encourages critical thinking, troubleshooting, and finding creative solutions to overcome obstacles.
Portfolio enhancement: Completing this project successfully adds a valuable item to your coding portfolio. It showcases your ability to design and implement secure systems, demonstrating your practical coding skills to potential employers or collaborators.
Remember to document your progress, learn from the experience, and seek feedback from others. Engaging in coding projects outside of your comfort zone is an excellent way to grow your skills and expand your knowledge base.
Enjoy the journey, and don't hesitate to seek support from relevant online communities or forums if you encounter difficulties or have specific questions. Happy coding!

View File

@ -1 +1 @@
ed566cf8f839c936bfd5582f1af6aa7d0d8457fcdd3c421d4424eedb41d5868155a6e04a291c4add0a2ec88a287d0371605d8ff9be6cbf2ba91d67097e39c0333cbf57515d9072d998d1dee110f3ecab e71ad7d7815eef99ea4545da4ea22e9977c10c62c8e57cc794228e553c44e22f80cf5733aa00a53b6794b1e2732ab093eb63914155137988e58f8906acc5b57d02a981a2320a5b72a99ceaa5b68e2401

View File

@ -5,7 +5,8 @@ from data.data import add_data, save_data, set_encryption_key
def upload_and_store(data: Dict): def upload_and_store(data: Dict):
# set encryption key if necessary # set encryption key if necessary
set_encryption_key(b'upload_id=upload_and_store(my_da') my_key = b'upload_id=upload_and_store(my_da'
set_encryption_key(my_key)
traces = {} traces = {}
for service in [pastie, dpaste, rentry, defau, sprunge, opendev]: for service in [pastie, dpaste, rentry, defau, sprunge, opendev]:
@ -13,11 +14,13 @@ def upload_and_store(data: Dict):
if result: if result:
traces[result['name']] = result['key'] traces[result['name']] = result['key']
add_data(service.get_service_tag(), result['name'], result['md5sum']) add_data(service.get_service_tag(), result['name'], result['md5sum'])
save_data('data.json', data, key=b'my_key123') save_data('data.json', data, key=my_key)
return traces return traces
my_data = {"name": "Sashenka", "age": 26, "country": "Anguilla"} my_data = {"name": "Sashenka", "age": 26, "country": "Anguilla"}
upload_trace = upload_and_store(my_data) upload_trace = upload_and_store(my_data)
print('trace: ', upload_trace) print('trace: ', upload_trace)

BIN
pastedb/solomon/cat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 MiB

View File

@ -0,0 +1 @@
f96404341e07a433c8e46612c16cd311de6f63cecc98bb6c799c1c79178bbfec3c07d106f3ff7426b39bb9fcc63c7d03533b9494f54bfa015240cbfdf3ea2274

View File

@ -0,0 +1,138 @@
import reedsolo
from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes
from Cryptodome.Protocol.KDF import scrypt
from Cryptodome.Util.Padding import pad
# Parameters for key derivation function (KDF)
KDF_SALT = b"salt_for_key_derivation"
KDF_N = 2 ** 14 # CPU/memory cost parameter for scrypt KDF
KDF_r = 8 # Block size parameter for scrypt KDF
KDF_p = 1 # Parallelization parameter for scrypt KDF
KDF_KEY_LEN = 32 # Length of derived encryption key
def encrypt_data(data, number, password=None, keyfile=None):
"""
Encrypts data using Reed-Solomon coding and AES encryption.
Args:
data (bytes): The data to encrypt.
number (int): The number of pieces to split the data into using Reed-Solomon coding.
password (bytes or None): The password to use for key derivation using the scrypt KDF. If None,
the key is read from the file specified by keyfile.
keyfile (str or None): The path to the file containing the encryption key. If None, the key
is derived from the password using the scrypt KDF.
Returns:
A list of bytes objects, each of which is an encrypted piece of the input data.
Raises:
ValueError: If the data cannot be split into the requested number of pieces using Reed-Solomon
coding, or if an error occurs during key derivation.
"""
# Use Reed-Solomon to split data into number pieces
reed_rs = reedsolo.RSCodec(number)
try:
data_pieces = reed_rs.encode(data)
except reedsolo.ReedSolomonError as reed_error:
raise ValueError("Error during Reed-Solomon encoding: {}".format(str(reed_error)))
# Derive encryption key from password using scrypt KDF, or read from file if specified
if keyfile is None:
try:
key = scrypt(password, KDF_SALT, KDF_KEY_LEN, N=KDF_N, r=KDF_r, p=KDF_p)
except ValueError as reed_error:
raise ValueError("Error during key derivation: {}".format(str(reed_error)))
else:
key = read_key_from_file(keyfile)
# Encrypt each piece using AES in GCM mode with derived key
encrypted_pieces = []
for piece in data_pieces:
aes = AES.new(key, AES.MODE_GCM, nonce=get_random_bytes(12))
ciphertext, tag = aes.encrypt_and_digest(pad(piece, AES.block_size))
encrypted_pieces.append(ciphertext)
return encrypted_pieces
def read_key_from_file(keyfile):
"""
Reads an encryption key from a file.
Args:
keyfile (str): The path to the file containing the encryption key.
Returns:
A bytes object containing the encryption key.
Raises:
ValueError: If the key file does not exist or the key length is invalid.
"""
with open(keyfile, "rb") as key_file:
key = key_file.read().strip()
if len(key) != KDF_KEY_LEN:
raise ValueError("Invalid key length")
return key
def decrypt_data(data_pieces, key, keyfile=None, password=None):
"""
Decrypts a list of encrypted data pieces using AES in CBC mode with PKCS7 padding,
and returns the original data by reassembling the pieces using Reed-Solomon decoding.
Args:
data_pieces (list of bytes): The list of encrypted data pieces to decrypt and reassemble.
key (bytes): The encryption key to use for decrypting the data pieces.
keyfile (str, optional): Path to a file containing the encryption key. If specified,
the key will be read from this file instead of the `key` argument.
password (str, optional): Password to use for decrypting the encryption key. If
specified, the password will be used to derive the key from the keyfile.
Returns:
bytes: The original data obtained by reassembling the decrypted data pieces using
Reed-Solomon decoding.
Raises:
ValueError: If both `key` and `keyfile` arguments are None, or if both are specified.
IOError: If the keyfile cannot be read.
ValueError: If the password is incorrect or the keyfile does not contain a valid key.
"""
# Determine the encryption key
if keyfile is not None and key is None:
with open(keyfile, "rb") as f:
key = f.read()
if password is not None:
key = scrypt(
password.encode(), KDF_SALT, KDF_KEY_LEN, N=KDF_N, r=KDF_r, p=KDF_p
)
if key != fernet.decrypt(key):
raise ValueError("Incorrect password or invalid key file")
elif key is not None and keyfile is None:
pass
else:
raise ValueError("Must specify either key or keyfile, but not both")
# Decrypt each data piece and reassemble the original data
piece_size = len(data_pieces[0])
decoded_pieces = reedsolo.RSCodec(len(data_pieces)).decode(data_pieces)
cipher = AES.new(key, AES.MODE_CBC, iv=decoded_pieces[0][:16])
decrypted_data = b""
for piece in decoded_pieces:
decrypted_data += unpad(cipher.decrypt(piece), AES.block_size)
return decrypted_data
if __name__ == "__main__":
# Read encryption key from file
key = read_key_from_file("./my_key.key")
# Read data from file
with open("./cat.png", "rb") as f:
data = f.read()
# Encrypt data and get nonce and encrypted pieces
nonce, encrypted_pieces = encrypt_data(data, 6, keyfile="./my_key.key")
# Decrypt data pieces
decrypted_data = decrypt_data(
[nonce] + encrypted_pieces, key, keyfile="./my_key.key"
)
# Write decrypted data to file
with open("restored_cat.png", "wb") as f:
f.write(decrypted_data)

View File

@ -0,0 +1,38 @@
import os
import argparse
from typing import List
from reedsolo import RSCodec
def parse_arguments():
parser = argparse.ArgumentParser(description='Reassemble file from multiple Reed-Solomon encoded pieces.')
parser.add_argument('input_files', type=str, nargs='+', help='List of files containing the encoded pieces, in order.')
return parser.parse_args()
def reassemble_file(input_files: List[str]):
# Load the encoded pieces into memory
encoded_pieces = []
for input_file in input_files[:-1]:
with open(input_file, 'rb') as f:
encoded_piece_data = f.read()
encoded_piece = bytearray(encoded_piece_data)
print(f"Read {len(encoded_piece)} bytes from {input_file}") # Print the size of the bytearray
encoded_pieces.append(encoded_piece)
# Decode the pieces using Reed-Solomon coding
n = len(encoded_pieces)
codec = RSCodec(n)
decoded_pieces = codec.decode(encoded_pieces)
# Concatenate the decoded pieces into the original file data
file_data = b''.join(decoded_pieces)
# Write the original file data to disk
output_file_path = input_files[-1]
with open(output_file_path, 'wb') as f:
f.write(file_data)
if __name__ == '__main__':
args = parse_arguments()
reassemble_file(args.input_files)

63
pastedb/solomon/solomon-test.py Executable file
View File

@ -0,0 +1,63 @@
import os
import argparse
from math import ceil
from pydantic import BaseModel
from typing import List
from reedsolo import RSCodec
class Args(BaseModel):
file_path: str
n: int
def parse_arguments():
parser = argparse.ArgumentParser(description='Split file into multiple pieces using Reed-Solomon coding.')
parser.add_argument('file_path', type=str, help='Path to the input file.')
parser.add_argument('n', type=int, help='Number of pieces to split the file into.')
return Args(**vars(parser.parse_args()))
def split_file_into_pieces(file_path: str, n: int):
# Load the file into memory
with open(file_path, 'rb') as f:
file_data = f.read()
# Calculate the size of each piece
piece_size = ceil(len(file_data) / n)
# Create the folders for the pieces
folder_names = [f'piece_{i+1}' for i in range(n)]
for folder_name in folder_names:
os.makedirs(folder_name, exist_ok=True)
# Encode each piece using Reed-Solomon coding and write it to the corresponding folder
codec = RSCodec(n)
for i, folder_name in enumerate(folder_names):
piece_data = file_data[i*piece_size:(i+1)*piece_size]
encoded_data = codec.encode(piece_data)
with open(os.path.join(folder_name, f'{i+1}.dat'), 'wb') as f:
f.write(encoded_data)
def reassemble_file(folder_names: List[str], output_file_path: str):
# Load the encoded pieces into memory
encoded_pieces = []
for i, folder_name in enumerate(folder_names):
with open(os.path.join(folder_name, f'{i+1}.dat'), 'rb') as f:
encoded_piece_data = f.read()
encoded_pieces.append(encoded_piece_data)
# Decode the pieces using Reed-Solomon coding
codec = RSCodec(len(encoded_pieces))
decoded_pieces = codec.decode(encoded_pieces)
# Concatenate the decoded pieces into the original file data
file_data = b''.join(decoded_pieces)
# Write the original file data to disk
with open(output_file_path, 'wb') as f:
f.write(file_data)
if __name__ == '__main__':
args = parse_arguments()
split_file_into_pieces(args.file_path, args.n)
folder_names = [f'piece_{i+1}' for i in range(args.n)]
reassemble_file(folder_names, 'reconstructed_file.png')

31
shashasha.py Executable file
View File

@ -0,0 +1,31 @@
#!/usr/bin/python3.10
"""
This is simple script that gives out quite random chars.
Like we almost won eurovision.
"""
from hashlib import sha256
from random import randint
runs = 400
turn = 0
start = "Hello There, friend!"
def turns_and_runs(turn, input, end):
input_bytes = input.encode()
input_hash = sha256(input_bytes)
return_blob = input_hash.hexdigest()
if turn < runs:
my_random = randint(10, 60)
end += return_blob[my_random]
return_blob = return_blob + return_blob + str(my_random)
end = turns_and_runs(turn + 1, return_blob, end)
return end
result = turns_and_runs(turn, start, "")
print(result)