Chapter 5: Cryptocurrency Wallets and Security
Haiyue
37min
Chapter 5: Cryptocurrency Wallets and Security
Learning Objectives
- Understand how wallets work
- Master the differences between hot wallets and cold wallets
- Learn private key, public key, and mnemonic phrase management
- Understand common security threats and protection measures
Wallet Fundamentals
Key Pair Generation and Management
Cryptocurrency wallets are essentially tools for managing key pairs and addresses:
import hashlib
import secrets
import hmac
from typing import List, Tuple, Dict
from dataclasses import dataclass
@dataclass
class KeyPair:
"""Key pair"""
private_key: str
public_key: str
address: str
class CryptographicWallet:
"""Cryptocurrency wallet"""
def __init__(self, entropy_bits: int = 128):
"""
Initialize wallet
entropy_bits: Entropy bits (128, 256, etc.)
"""
self.entropy_bits = entropy_bits
self.master_seed = None
self.mnemonic = None
self.accounts: Dict[str, KeyPair] = {}
def generate_mnemonic(self, language: str = "english") -> List[str]:
"""Generate mnemonic phrase"""
# Generate random entropy
entropy = secrets.randbits(self.entropy_bits)
entropy_bytes = entropy.to_bytes(self.entropy_bits // 8, 'big')
# Calculate checksum
checksum_bits = self.entropy_bits // 32
hash_bytes = hashlib.sha256(entropy_bytes).digest()
checksum = int.from_bytes(hash_bytes, 'big') >> (256 - checksum_bits)
# Combine entropy and checksum
total_bits = self.entropy_bits + checksum_bits
combined = (entropy << checksum_bits) | checksum
# Convert to mnemonic words (simplified implementation)
word_count = total_bits // 11
mnemonic_words = []
# Simplified BIP39 word list (should contain full 2048 words)
bip39_words = [
"abandon", "ability", "able", "about", "above", "absent", "absorb",
"abstract", "absurd", "abuse", "access", "accident", "account",
"accuse", "achieve", "acid", "acoustic", "acquire", "across", "act",
"action", "actor", "actress", "actual", "adapt", "add", "addict"
] * 80 # Extended to sufficient quantity
for i in range(word_count):
word_index = (combined >> (total_bits - (i + 1) * 11)) & 0x7FF
word_index = word_index % len(bip39_words)
mnemonic_words.append(bip39_words[word_index])
self.mnemonic = mnemonic_words
return mnemonic_words
def create_seed_from_mnemonic(self, mnemonic: List[str],
passphrase: str = "") -> bytes:
"""Generate seed from mnemonic phrase"""
mnemonic_str = " ".join(mnemonic)
salt = "mnemonic" + passphrase
# Generate 512-bit seed using PBKDF2
seed = hashlib.pbkdf2_hmac(
'sha512',
mnemonic_str.encode('utf-8'),
salt.encode('utf-8'),
2048, # Iteration count
64 # Output length (512 bits)
)
self.master_seed = seed
return seed
def derive_key_pair(self, derivation_path: str = "m/44'/0'/0'/0/0") -> KeyPair:
"""Generate key pair based on derivation path (simplified implementation)"""
if not self.master_seed:
raise ValueError("Must generate seed first")
# Simplified key derivation (should use BIP32 standard)
path_hash = hashlib.sha256(
(derivation_path + str(len(self.accounts))).encode()
).digest()
# Generate private key
private_key_bytes = hmac.new(
self.master_seed,
path_hash,
hashlib.sha256
).digest()
private_key = private_key_bytes.hex()
# Generate public key (simplified: using private key hash)
public_key = hashlib.sha256(private_key_bytes).hexdigest()
# Generate address (simplified: using RIPEMD160 of public key)
address_bytes = hashlib.new(
'ripemd160',
bytes.fromhex(public_key)
).digest()
address = "1" + address_bytes.hex() # Simplified address format
key_pair = KeyPair(private_key, public_key, address)
self.accounts[address] = key_pair
return key_pair
def sign_transaction(self, private_key: str, transaction_data: str) -> str:
"""Sign transaction (simplified implementation)"""
# Should use ECDSA algorithm
signature = hmac.new(
bytes.fromhex(private_key),
transaction_data.encode(),
hashlib.sha256
).hexdigest()
return signature
def verify_signature(self, public_key: str, transaction_data: str,
signature: str) -> bool:
"""Verify signature (simplified implementation)"""
# This is simplified, actual implementation needs elliptic curve cryptography
return len(signature) == 64 # Simple length check
def export_wallet(self, password: str) -> Dict:
"""Export wallet (encrypted)"""
if not self.mnemonic:
raise ValueError("Wallet not initialized")
# Encrypt mnemonic
encrypted_mnemonic = self._encrypt_data(" ".join(self.mnemonic), password)
wallet_data = {
"version": "1.0",
"encrypted_mnemonic": encrypted_mnemonic,
"accounts": {
addr: {
"address": kp.address,
"public_key": kp.public_key
# Don't export private key, re-derive from mnemonic
}
for addr, kp in self.accounts.items()
}
}
return wallet_data
def import_wallet(self, wallet_data: Dict, password: str):
"""Import wallet"""
try:
# Decrypt mnemonic
encrypted_mnemonic = wallet_data["encrypted_mnemonic"]
mnemonic_str = self._decrypt_data(encrypted_mnemonic, password)
self.mnemonic = mnemonic_str.split()
# Regenerate seed and keys
self.create_seed_from_mnemonic(self.mnemonic)
# Re-derive accounts
for i in range(len(wallet_data["accounts"])):
self.derive_key_pair(f"m/44'/0'/0'/0/{i}")
print("Wallet import successful")
except Exception as e:
raise ValueError(f"Wallet import failed: {e}")
def _encrypt_data(self, data: str, password: str) -> str:
"""Encrypt data (simplified implementation)"""
# Should use strong encryption like AES
password_hash = hashlib.sha256(password.encode()).digest()
encrypted = bytes(a ^ b for a, b in zip(data.encode(), password_hash[:len(data.encode())]))
return encrypted.hex()
def _decrypt_data(self, encrypted_hex: str, password: str) -> str:
"""Decrypt data (simplified implementation)"""
encrypted = bytes.fromhex(encrypted_hex)
password_hash = hashlib.sha256(password.encode()).digest()
decrypted = bytes(a ^ b for a, b in zip(encrypted, password_hash[:len(encrypted)]))
return decrypted.decode()
# Wallet usage demonstration
print("=== Cryptocurrency Wallet Demo ===")
# Create new wallet
wallet = CryptographicWallet(entropy_bits=128)
# Generate mnemonic
mnemonic = wallet.generate_mnemonic()
print(f"Mnemonic: {' '.join(mnemonic)}")
# Generate seed
seed = wallet.create_seed_from_mnemonic(mnemonic)
print(f"Seed (hex): {seed.hex()[:32]}...")
# Derive key pairs
key_pair1 = wallet.derive_key_pair("m/44'/0'/0'/0/0")
key_pair2 = wallet.derive_key_pair("m/44'/0'/0'/0/1")
print(f"\nAccount 1:")
print(f" Address: {key_pair1.address}")
print(f" Public Key: {key_pair1.public_key[:16]}...")
print(f" Private Key: {key_pair1.private_key[:16]}...")
print(f"\nAccount 2:")
print(f" Address: {key_pair2.address}")
# Sign transaction
tx_data = "Alice sends 1 BTC to Bob"
signature = wallet.sign_transaction(key_pair1.private_key, tx_data)
print(f"\nTransaction Signature: {signature[:16]}...")
# Verify signature
is_valid = wallet.verify_signature(key_pair1.public_key, tx_data, signature)
print(f"Signature Verification: {is_valid}")
Wallet Type Classification
Hot Wallets vs Cold Wallets
from enum import Enum
import time
from abc import ABC, abstractmethod
class WalletType(Enum):
"""Wallet types"""
HOT = "hot_wallet" # Hot wallet
COLD = "cold_wallet" # Cold wallet
HARDWARE = "hardware_wallet" # Hardware wallet
PAPER = "paper_wallet" # Paper wallet
class BaseWallet(ABC):
"""Base wallet class"""
def __init__(self, wallet_type: WalletType):
self.wallet_type = wallet_type
self.created_at = time.time()
self.last_backup = None
@abstractmethod
def create_transaction(self, to_address: str, amount: float) -> Dict:
pass
@abstractmethod
def sign_transaction(self, transaction: Dict) -> str:
pass
@abstractmethod
def get_security_level(self) -> int:
pass
class HotWallet(BaseWallet):
"""Hot wallet (online)"""
def __init__(self):
super().__init__(WalletType.HOT)
self.is_online = True
self.auto_sync = True
self.convenience_features = ["Quick transactions", "Real-time prices", "DApp connection"]
def create_transaction(self, to_address: str, amount: float) -> Dict:
"""Create transaction (hot wallet)"""
transaction = {
"from": "hot_wallet_address",
"to": to_address,
"amount": amount,
"timestamp": time.time(),
"gas_price": self._get_current_gas_price(),
"nonce": self._get_account_nonce()
}
print(f"Hot wallet transaction created: {amount} -> {to_address}")
print(f"Current Gas price: {transaction['gas_price']} Gwei")
return transaction
def sign_transaction(self, transaction: Dict) -> str:
"""Sign transaction"""
# Hot wallet can sign immediately
signature = f"hot_sig_{hash(str(transaction)) % 100000}"
print(f"Hot wallet instant signature: {signature}")
return signature
def get_security_level(self) -> int:
"""Security level (1-10)"""
return 6 # Medium security
def connect_to_dapp(self, dapp_url: str) -> bool:
"""Connect to DApp"""
if self.is_online:
print(f"Connected to DApp: {dapp_url}")
return True
return False
def _get_current_gas_price(self) -> float:
"""Get current gas price"""
# Simulate fetching real-time gas price from network
return 25.0 # Gwei
def _get_account_nonce(self) -> int:
"""Get account nonce"""
return int(time.time()) % 1000
class ColdWallet(BaseWallet):
"""Cold wallet (offline)"""
def __init__(self):
super().__init__(WalletType.COLD)
self.is_online = False
self.air_gapped = True # Air-gapped
self.security_features = ["Offline storage", "Multi-signature", "Backup mechanism"]
def create_transaction(self, to_address: str, amount: float) -> Dict:
"""Create transaction (cold wallet)"""
# Cold wallet requires manual network parameters
transaction = {
"from": "cold_wallet_address",
"to": to_address,
"amount": amount,
"timestamp": time.time(),
"gas_price": self._get_manual_gas_price(),
"nonce": self._get_manual_nonce()
}
print(f"Cold wallet transaction created: {amount} -> {to_address}")
print("Warning: Manual network parameter setting required")
return transaction
def sign_transaction(self, transaction: Dict) -> str:
"""Offline sign transaction"""
print("Starting offline signing process...")
print("1. Verify transaction details")
print("2. Confirm signing operation")
print("3. Generate signature")
signature = f"cold_sig_{hash(str(transaction)) % 100000}"
print(f"Cold wallet offline signing completed: {signature}")
return signature
def get_security_level(self) -> int:
"""Security level (1-10)"""
return 10 # Maximum security
def export_signed_transaction(self, transaction: Dict, signature: str) -> str:
"""Export signed transaction"""
signed_tx = {
"transaction": transaction,
"signature": signature,
"export_time": time.time()
}
# Simulate export as QR code or file
export_data = f"signed_tx_{hash(str(signed_tx)) % 100000}.txt"
print(f"Signed transaction exported: {export_data}")
return export_data
def _get_manual_gas_price(self) -> float:
"""Manually set gas price"""
# Cold wallet user needs to manually query and input
return 30.0 # Gwei
def _get_manual_nonce(self) -> int:
"""Manually set nonce"""
return 42 # User manual input
class HardwareWallet(BaseWallet):
"""Hardware wallet"""
def __init__(self, device_model: str):
super().__init__(WalletType.HARDWARE)
self.device_model = device_model
self.firmware_version = "1.0.0"
self.is_connected = False
self.pin_required = True
def connect_device(self, pin: str) -> bool:
"""Connect hardware device"""
if self._verify_pin(pin):
self.is_connected = True
print(f"Success: {self.device_model} connected")
return True
else:
print("Error: Incorrect PIN")
return False
def create_transaction(self, to_address: str, amount: float) -> Dict:
"""Create transaction"""
if not self.is_connected:
raise Exception("Hardware wallet not connected")
transaction = {
"from": "hardware_wallet_address",
"to": to_address,
"amount": amount,
"timestamp": time.time()
}
print(f"Hardware wallet transaction prepared: {amount} -> {to_address}")
return transaction
def sign_transaction(self, transaction: Dict) -> str:
"""Hardware signature"""
if not self.is_connected:
raise Exception("Hardware wallet not connected")
print("Please confirm transaction on hardware device...")
print("1. Verify recipient address")
print("2. Confirm transaction amount")
print("3. Press confirm button")
# Simulate user confirmation
user_confirmed = True # Actual implementation needs hardware interaction
if user_confirmed:
signature = f"hw_sig_{hash(str(transaction)) % 100000}"
print(f"Success: Hardware signature completed: {signature}")
return signature
else:
raise Exception("User cancelled transaction")
def get_security_level(self) -> int:
"""Security level"""
return 9 # High security
def _verify_pin(self, pin: str) -> bool:
"""Verify PIN"""
return len(pin) >= 4 # Simplified verification
# Wallet type comparison demonstration
print("\n=== Wallet Type Comparison Demo ===")
# Create different types of wallets
hot_wallet = HotWallet()
cold_wallet = ColdWallet()
hardware_wallet = HardwareWallet("Ledger Nano S")
wallets = [
("Hot Wallet", hot_wallet),
("Cold Wallet", cold_wallet),
("Hardware Wallet", hardware_wallet)
]
# Compare wallet features
print("Wallet Feature Comparison:")
print(f"{'Wallet Type':15} {'Security':10} {'Convenience':12} {'Use Case':25}")
print("-" * 65)
wallet_features = {
"Hot Wallet": {"Security": 6, "Convenience": 10, "Use Case": "Daily small transactions"},
"Cold Wallet": {"Security": 10, "Convenience": 3, "Use Case": "Long-term storage"},
"Hardware Wallet": {"Security": 9, "Convenience": 7, "Use Case": "Frequent trading + security"}
}
for wallet_name, features in wallet_features.items():
print(f"{wallet_name:15} {features['Security']:10} {features['Convenience']:12} {features['Use Case']:25}")
# Simulate transaction process comparison
print(f"\n=== Transaction Process Comparison ===")
transaction_details = {
"to_address": "1ABC...xyz",
"amount": 0.5
}
for wallet_name, wallet in wallets:
print(f"\n{wallet_name} Transaction Process:")
try:
if wallet_name == "Hardware Wallet":
wallet.connect_device("1234")
tx = wallet.create_transaction(**transaction_details)
signature = wallet.sign_transaction(tx)
print(f"Security Level: {wallet.get_security_level()}/10")
except Exception as e:
print(f"Transaction failed: {e}")
Mnemonic Phrase and Seed Management
BIP39 Mnemonic Standard
import secrets
import hashlib
from typing import List, Optional
class BIP39:
"""BIP39 mnemonic standard implementation"""
# Simplified BIP39 word list (actual standard contains 2048 words)
WORDLIST = [
"abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract",
"absurd", "abuse", "access", "accident", "account", "accuse", "achieve", "acid",
"acoustic", "acquire", "across", "act", "action", "actor", "actress", "actual",
"adapt", "add", "addict", "address", "adjust", "admit", "adult", "advance",
# ... should contain 2048 words
] * 64 # Extended to 2048
@classmethod
def generate_mnemonic(cls, strength: int = 128) -> List[str]:
"""
Generate mnemonic phrase
strength: Entropy strength (128, 160, 192, 224, 256)
"""
if strength not in [128, 160, 192, 224, 256]:
raise ValueError("Strength must be 128, 160, 192, 224, or 256")
# Generate random entropy
entropy_bytes = secrets.randbits(strength).to_bytes(strength // 8, 'big')
# Calculate checksum
checksum_length = strength // 32
hash_bytes = hashlib.sha256(entropy_bytes).digest()
checksum = int.from_bytes(hash_bytes, 'big') >> (256 - checksum_length)
# Combine entropy and checksum
entropy_with_checksum = (int.from_bytes(entropy_bytes, 'big') << checksum_length) | checksum
total_bits = strength + checksum_length
# Convert to mnemonic words
mnemonic_length = total_bits // 11
mnemonic = []
for i in range(mnemonic_length):
word_index = (entropy_with_checksum >> (total_bits - (i + 1) * 11)) & 0x7FF
word_index = word_index % len(cls.WORDLIST)
mnemonic.append(cls.WORDLIST[word_index])
return mnemonic
@classmethod
def mnemonic_to_seed(cls, mnemonic: List[str], passphrase: str = "") -> bytes:
"""Convert mnemonic phrase to seed"""
mnemonic_str = " ".join(mnemonic)
salt = "mnemonic" + passphrase
# Use PBKDF2-HMAC-SHA512
seed = hashlib.pbkdf2_hmac(
'sha512',
mnemonic_str.encode('utf-8'),
salt.encode('utf-8'),
2048, # Iteration count
64 # Output length (512 bits)
)
return seed
@classmethod
def validate_mnemonic(cls, mnemonic: List[str]) -> bool:
"""Validate mnemonic phrase"""
if len(mnemonic) not in [12, 15, 18, 21, 24]:
return False
# Check if words are in wordlist
for word in mnemonic:
if word not in cls.WORDLIST:
return False
# Validate checksum (simplified implementation)
return True
@classmethod
def get_entropy_from_mnemonic(cls, mnemonic: List[str]) -> bytes:
"""Recover entropy from mnemonic phrase"""
if not cls.validate_mnemonic(mnemonic):
raise ValueError("Invalid mnemonic phrase")
# Convert to bit sequence
total_bits = len(mnemonic) * 11
entropy_bits = (total_bits * 32) // 33
combined = 0
for word in mnemonic:
word_index = cls.WORDLIST.index(word)
combined = (combined << 11) | word_index
# Extract entropy
entropy = combined >> (total_bits - entropy_bits)
entropy_bytes = entropy.to_bytes(entropy_bits // 8, 'big')
return entropy_bytes
class SecureMnemonicStorage:
"""Secure mnemonic storage"""
def __init__(self):
self.encrypted_storage = {}
def store_mnemonic(self, mnemonic: List[str], password: str,
storage_id: str) -> Dict:
"""Securely store mnemonic phrase"""
# Generate storage key
storage_key = self._derive_storage_key(password, storage_id)
# Encrypt mnemonic
mnemonic_str = " ".join(mnemonic)
encrypted_mnemonic = self._encrypt_aes(mnemonic_str, storage_key)
# Generate checksum
checksum = hashlib.sha256(mnemonic_str.encode()).hexdigest()[:8]
storage_data = {
"encrypted_mnemonic": encrypted_mnemonic.hex(),
"checksum": checksum,
"timestamp": time.time(),
"version": "1.0"
}
self.encrypted_storage[storage_id] = storage_data
return {
"storage_id": storage_id,
"checksum": checksum,
"status": "success"
}
def retrieve_mnemonic(self, storage_id: str, password: str) -> List[str]:
"""Retrieve mnemonic phrase"""
if storage_id not in self.encrypted_storage:
raise ValueError("Storage ID does not exist")
storage_data = self.encrypted_storage[storage_id]
# Generate decryption key
storage_key = self._derive_storage_key(password, storage_id)
try:
# Decrypt mnemonic
encrypted_bytes = bytes.fromhex(storage_data["encrypted_mnemonic"])
decrypted_str = self._decrypt_aes(encrypted_bytes, storage_key)
# Verify checksum
checksum = hashlib.sha256(decrypted_str.encode()).hexdigest()[:8]
if checksum != storage_data["checksum"]:
raise ValueError("Checksum verification failed")
mnemonic = decrypted_str.split()
# Validate mnemonic
if not BIP39.validate_mnemonic(mnemonic):
raise ValueError("Mnemonic validation failed")
return mnemonic
except Exception as e:
raise ValueError(f"Mnemonic retrieval failed: {e}")
def _derive_storage_key(self, password: str, storage_id: str) -> bytes:
"""Derive storage key"""
salt = storage_id.encode('utf-8')
key = hashlib.pbkdf2_hmac(
'sha256',
password.encode('utf-8'),
salt,
100000, # Iteration count
32 # Key length
)
return key
def _encrypt_aes(self, plaintext: str, key: bytes) -> bytes:
"""AES encryption (simplified implementation)"""
# Should use authenticated encryption modes like AES-GCM
data = plaintext.encode('utf-8')
key_hash = hashlib.sha256(key).digest()
encrypted = bytes(a ^ b for a, b in zip(data, key_hash[:len(data)]))
return encrypted
def _decrypt_aes(self, ciphertext: bytes, key: bytes) -> str:
"""AES decryption (simplified implementation)"""
key_hash = hashlib.sha256(key).digest()
decrypted = bytes(a ^ b for a, b in zip(ciphertext, key_hash[:len(ciphertext)]))
return decrypted.decode('utf-8')
# Mnemonic management demonstration
print("\n=== Mnemonic Management Demo ===")
# Generate mnemonics with different strengths
print("Generate mnemonics with different strengths:")
for strength in [128, 192, 256]:
mnemonic = BIP39.generate_mnemonic(strength)
word_count = len(mnemonic)
print(f"{strength}-bit entropy ({word_count} words): {' '.join(mnemonic[:4])}...")
# Full mnemonic example
sample_mnemonic = BIP39.generate_mnemonic(128)
print(f"\nFull mnemonic example: {' '.join(sample_mnemonic)}")
# Generate seed
seed = BIP39.mnemonic_to_seed(sample_mnemonic)
print(f"Seed (hex): {seed.hex()}")
# Seed generation with passphrase
seed_with_passphrase = BIP39.mnemonic_to_seed(sample_mnemonic, "MySecretPassphrase")
print(f"Seed with passphrase: {seed_with_passphrase.hex()}")
# Secure storage demonstration
print(f"\n=== Secure Mnemonic Storage Demo ===")
storage = SecureMnemonicStorage()
# Store mnemonic
storage_result = storage.store_mnemonic(
mnemonic=sample_mnemonic,
password="MyStrongPassword123!",
storage_id="wallet_backup_001"
)
print(f"Storage result: {storage_result}")
# Retrieve mnemonic
try:
retrieved_mnemonic = storage.retrieve_mnemonic(
storage_id="wallet_backup_001",
password="MyStrongPassword123!"
)
print(f"Retrieval successful: {retrieved_mnemonic == sample_mnemonic}")
print(f"Retrieved mnemonic: {' '.join(retrieved_mnemonic[:4])}...")
except ValueError as e:
print(f"Retrieval failed: {e}")
Common Security Threats and Protection
Security Threat Classification
from enum import Enum
from typing import Dict, List
import re
class ThreatLevel(Enum):
"""Threat levels"""
LOW = 1
MEDIUM = 2
HIGH = 3
CRITICAL = 4
class ThreatType(Enum):
"""Threat types"""
PHISHING = "Phishing Attack"
MALWARE = "Malware"
SOCIAL_ENGINEERING = "Social Engineering"
MAN_IN_THE_MIDDLE = "Man-in-the-Middle Attack"
CLIPBOARD_HIJACKING = "Clipboard Hijacking"
FAKE_WALLET = "Fake Wallet"
PRIVATE_KEY_EXPOSURE = "Private Key Exposure"
WEAK_PASSWORD = "Weak Password"
@dataclass
class SecurityThreat:
"""Security threat"""
threat_type: ThreatType
level: ThreatLevel
description: str
attack_vectors: List[str]
prevention_measures: List[str]
class SecurityAnalyzer:
"""Security analyzer"""
def __init__(self):
self.known_threats = self._initialize_threats()
self.security_patterns = self._initialize_patterns()
def _initialize_threats(self) -> Dict[ThreatType, SecurityThreat]:
"""Initialize threat database"""
threats = {
ThreatType.PHISHING: SecurityThreat(
threat_type=ThreatType.PHISHING,
level=ThreatLevel.HIGH,
description="Stealing user credentials through fake websites or emails",
attack_vectors=[
"Fake exchange websites",
"Phishing emails",
"Social media links",
"Malicious ads"
],
prevention_measures=[
"Verify website SSL certificate",
"Check URL spelling",
"Use official apps",
"Enable two-factor authentication"
]
),
ThreatType.MALWARE: SecurityThreat(
threat_type=ThreatType.MALWARE,
level=ThreatLevel.CRITICAL,
description="Malicious software stealing private keys or tampering with transactions",
attack_vectors=[
"Keyloggers",
"Clipboard viruses",
"Fake wallet software",
"Browser extensions"
],
prevention_measures=[
"Use antivirus software",
"Regular system scans",
"Download software only from official sources",
"Use hardware wallet"
]
),
ThreatType.CLIPBOARD_HIJACKING: SecurityThreat(
threat_type=ThreatType.CLIPBOARD_HIJACKING,
level=ThreatLevel.HIGH,
description="Malware replacing addresses in clipboard",
attack_vectors=[
"Memory-resident viruses",
"Background monitoring programs",
"Browser extension hijacking"
],
prevention_measures=[
"Manually verify addresses",
"Use address book",
"Verify in segments",
"Confirm with hardware wallet"
]
)
}
return threats
def _initialize_patterns(self) -> Dict[str, re.Pattern]:
"""Initialize security pattern matching"""
return {
"suspicious_url": re.compile(r".*\.(tk|ml|ga|cf)/.*|.*xn--.*"),
"weak_password": re.compile(r"^.{0,7}$|^[a-z]+$|^[A-Z]+$|^[0-9]+$"),
"bitcoin_address": re.compile(r"^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$"),
"ethereum_address": re.compile(r"^0x[a-fA-F0-9]{40}$")
}
def analyze_url_safety(self, url: str) -> Dict:
"""Analyze URL safety"""
risk_score = 0
warnings = []
# Check suspicious domains
if self.security_patterns["suspicious_url"].match(url):
risk_score += 30
warnings.append("Suspicious top-level domain")
# Check HTTPS
if not url.startswith("https://"):
risk_score += 20
warnings.append("Not using HTTPS encryption")
# Check common phishing patterns
phishing_patterns = [
"bin4nce", "coinb4se", "block-chain",
"meta-mask", "my-ether-wallet"
]
for pattern in phishing_patterns:
if pattern in url.lower():
risk_score += 50
warnings.append(f"Phishing pattern detected: {pattern}")
# Assess risk level
if risk_score >= 50:
risk_level = ThreatLevel.CRITICAL
elif risk_score >= 30:
risk_level = ThreatLevel.HIGH
elif risk_score >= 15:
risk_level = ThreatLevel.MEDIUM
else:
risk_level = ThreatLevel.LOW
return {
"url": url,
"risk_score": risk_score,
"risk_level": risk_level,
"warnings": warnings,
"safe": risk_score < 15
}
def validate_address(self, address: str, currency: str = "bitcoin") -> Dict:
"""Validate address format"""
if currency.lower() == "bitcoin":
pattern = self.security_patterns["bitcoin_address"]
elif currency.lower() == "ethereum":
pattern = self.security_patterns["ethereum_address"]
else:
return {"valid": False, "error": "Unsupported currency type"}
is_valid = bool(pattern.match(address))
return {
"address": address,
"currency": currency,
"valid": is_valid,
"format_check": "Pass" if is_valid else "Fail"
}
def check_password_strength(self, password: str) -> Dict:
"""Check password strength"""
score = 0
recommendations = []
# Length check
if len(password) >= 12:
score += 25
elif len(password) >= 8:
score += 15
else:
recommendations.append("Password should be at least 8 characters, 12+ recommended")
# Character complexity
if re.search(r"[a-z]", password):
score += 10
else:
recommendations.append("Include lowercase letters")
if re.search(r"[A-Z]", password):
score += 10
else:
recommendations.append("Include uppercase letters")
if re.search(r"[0-9]", password):
score += 10
else:
recommendations.append("Include numbers")
if re.search(r"[!@#$%^&*(),.?\":{}|<>]", password):
score += 15
else:
recommendations.append("Include special characters")
# Common pattern check
common_patterns = ["123456", "password", "qwerty", "abc", "111"]
for pattern in common_patterns:
if pattern in password.lower():
score -= 20
recommendations.append("Avoid common patterns")
break
# Rating
if score >= 70:
strength = "Strong"
elif score >= 50:
strength = "Medium"
elif score >= 30:
strength = "Weak"
else:
strength = "Very Weak"
return {
"score": max(0, score),
"strength": strength,
"recommendations": recommendations
}
def security_checklist(self) -> Dict:
"""Security checklist"""
return {
"Wallet Security": [
"Use hardware wallet for large amounts",
"Regular mnemonic backups",
"Use strong passwords and 2FA",
"Verify software source and integrity"
],
"Transaction Security": [
"Double-check recipient address",
"Verify transaction fee reasonableness",
"Test with small amount before large transfer",
"Use trusted RPC nodes"
],
"Network Security": [
"Use VPN for privacy protection",
"Avoid public WiFi for transactions",
"Regular software and system updates",
"Use official websites and apps"
],
"Storage Security": [
"Multiple mnemonic backups",
"Physical secure storage",
"Avoid digital private key storage",
"Regular backup validity checks"
]
}
# Security analysis demonstration
print("\n=== Cryptocurrency Security Analysis Demo ===")
analyzer = SecurityAnalyzer()
# URL safety analysis
test_urls = [
"https://www.binance.com",
"http://bin4nce.tk/login",
"https://metamask.io",
"https://my-ether-wallet.com"
]
print("URL Safety Analysis:")
for url in test_urls:
result = analyzer.analyze_url_safety(url)
safety_status = "Safe" if result["safe"] else "Warning: Dangerous"
print(f" {url}")
print(f" {safety_status} (Risk score: {result['risk_score']})")
if result["warnings"]:
print(f" Warnings: {', '.join(result['warnings'])}")
print()
# Address validation
print("Address Format Validation:")
test_addresses = [
("1BvBMSEYstWetqTFn5Au4m4GFg7xJaNVN2", "bitcoin"),
("0x742d35Cc6634C0532925a3b8D45d70c55e7c8f08", "ethereum"),
("invalid_address_123", "bitcoin")
]
for address, currency in test_addresses:
result = analyzer.validate_address(address, currency)
status = "Valid" if result["valid"] else "Invalid"
print(f" {address[:20]}... ({currency}): {status}")
# Password strength check
print("\nPassword Strength Analysis:")
test_passwords = [
"password123",
"MyStr0ng!P@ssw0rd2024",
"abc123",
"Blockchain$Security#2024"
]
for password in test_passwords:
result = analyzer.check_password_strength(password)
print(f" Password: {'*' * len(password)}")
print(f" Strength: {result['strength']} ({result['score']}/100)")
if result["recommendations"]:
print(f" Recommendations: {', '.join(result['recommendations'][:2])}")
print()
# Security checklist
print("=== Security Checklist ===")
checklist = analyzer.security_checklist()
for category, items in checklist.items():
print(f"\n{category}:")
for item in items:
print(f" - {item}")
Chapter Summary
This chapter comprehensively covered cryptocurrency wallets and security management:
-
Wallet Fundamentals:
- Key pair generation and management
- Mnemonic phrase and seed mechanism
- Address derivation algorithms
-
Wallet Types:
- Hot Wallets: Convenient but higher risk
- Cold Wallets: Secure but less convenient
- Hardware Wallets: Balance between security and convenience
-
Mnemonic Management:
- BIP39 standard implementation
- Secure storage and recovery
- Passphrase protection
-
Security Threat Protection:
- Phishing attack identification
- Malware protection
- Password security management
- Address verification mechanisms
-
Best Practices:
- Multiple backup strategies
- Security checklists
- Tiered storage solutions
- Regular security audits
Understanding and mastering these security concepts is crucial for safely using cryptocurrencies. In the next chapter, we will learn about the fundamentals of cryptocurrency transactions.