Geração de Frases Mnemônicas com Validação BIP44
Sempre crie uma frase de segurança única para jogos, testnets ou airdrops e evite usar sua carteira principal.
Como gerar e armazenar frases mnemônicas com chave privada e WIF usando Python e SQLite
Neste guia técnico, apresentamos um script completo em Python capaz de gerar frases mnemônicas com base na estrutura BIP-39, derivar chaves privadas e convertê-las para o formato WIF (Wallet Import Format). Além disso, os dados gerados são armazenados em um banco de dados local SQLite, permitindo o controle e persistência das informações.
O que é uma frase mnemônica BIP-39?
Uma frase mnemônica é uma representação amigável e legível por humanos de uma semente criptográfica. O padrão BIP-39 define como essas palavras são utilizadas para gerar chaves privadas seguras.
Objetivo do script
O script Python a seguir tem como objetivo:
- Combinar palavras mnemônicas para formar frases completas
- Validar se uma frase gera uma chave privada válida
- Converter a chave para o formato WIF
- Registrar os dados em uma base SQLite
- Permitir a retomada do processo a partir da última frase salva
Pré-requisitos
Certifique-se de ter as seguintes bibliotecas instaladas:
pip install bip_utils
Além disso, crie um arquivo palavras.txt contendo as palavras permitidas no padrão BIP-39, uma por linha.
Exemplo de estrutura do banco de dados SQLite
O banco controle.db possui uma tabela chamada mnemonics com os seguintes campos:
id– identificador autoincrementávelfrase– frase mnemônica completaprivate_key– chave privada derivadawif– chave privada no formato Wallet Import Format
Script Python completo
import os
import sys
from bip_utils import Bip39SeedGenerator, Bip44, Bip44Coins
import itertools
import sqlite3
def criar_tabela_se_nao_existir():
with sqlite3.connect('controle.db') as conn:
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS mnemonics (
id INTEGER PRIMARY KEY AUTOINCREMENT,
frase TEXT NOT NULL,
private_key TEXT NOT NULL,
wif TEXT NOT NULL
)
''')
conn.commit()
def inserir_dados_em_bloco(frases):
with sqlite3.connect('controle.db') as conn:
cursor = conn.cursor()
cursor.executemany('''INSERT INTO mnemonics (frase, private_key, wif) VALUES (?, ?, ?)''', frases)
conn.commit()
def obter_ultima_frase():
with sqlite3.connect('controle.db') as conn:
cursor = conn.cursor()
cursor.execute('''SELECT frase FROM mnemonics ORDER BY ROWID DESC LIMIT 1''')
ultima_frase = cursor.fetchone()
return ultima_frase[0] if ultima_frase else None
def frase_existe(frase):
with sqlite3.connect('controle.db') as conn:
cursor = conn.cursor()
cursor.execute('''SELECT COUNT(*) FROM mnemonics WHERE frase = ?''', (frase,))
existe = cursor.fetchone()[0] > 0
return existe
def frase_gera_chave_privada_valida(frase):
try:
seed_bytes = Bip39SeedGenerator(frase).Generate()
bip44 = Bip44.FromSeed(seed_bytes, Bip44Coins.BITCOIN)
chave_privada = bip44.PrivateKey().Raw().ToHex()
wif = bip44.PrivateKey().ToWif()
return chave_privada, wif
except Exception:
return None, None
def carregar_palavras():
try:
with open('palavras.txt', 'r') as f:
palavras = f.read().splitlines()
return palavras
except FileNotFoundError:
print("Arquivo palavras.txt não encontrado.")
sys.exit(1)
def gerar_frases():
iniciodafrase = 'repair either cricket vocal riot vast wink engage puzzle ...'
palavras = carregar_palavras()
combinacoes_ultimas_palavras = itertools.product(palavras, repeat=3)
ultima_frase = obter_ultima_frase()
continuar = False if ultima_frase else True
contador = 0
descartada = 0
bloco_frases = []
for combinacao in combinacoes_ultimas_palavras:
frasecompleta = iniciodafrase + ' ' + ' '.join(combinacao)
if ultima_frase and not continuar:
if frasecompleta == ultima_frase:
continuar = True
continue
try:
chave_privada, wif = frase_gera_chave_privada_valida(frasecompleta)
if chave_privada and wif:
if not frase_existe(frasecompleta):
bloco_frases.append((frasecompleta, chave_privada, wif))
contador += 1
print(f"Frases: {contador}", end="\r")
if contador == 1000:
inserir_dados_em_bloco(bloco_frases)
bloco_frases.clear()
print(f'\n{contador} frases inseridas.\n', end="\r")
print(f"Frases: {frasecompleta}\n", end="\r")
else:
descartada += 1
print(f'Descartadas: {descartada}', end="\r")
except Exception:
descartada += 1
print(f'Descartadas: {descartada}', end="\r")
continue
if bloco_frases:
inserir_dados_em_bloco(bloco_frases)
print(f'{contador} frases inseridas no final.')
criar_tabela_se_nao_existir()
gerar_frases()
Exemplo prático de entrada e saída
- Entrada: "trim skill build repair either cricket vocal riot vast wink engage puzzle poem bike wall joke august size improve note smooth odor hammer tooth"
- Saída: chave privada + chave em formato WIF armazenadas no banco SQLite
Considerações finais
Esse processo é útil em estudos sobre geração determinística de chaves e exploração de carteiras. Nunca reutilize essas frases ou chaves em ambientes reais sem o devido conhecimento de segurança.
Atenção: Este conteúdo é apenas para fins educacionais. Cabe a cada usuário realizar uma autoanálise e evitar qualquer aplicação prática sem conhecimento técnico aprofundado. Não invista nem utilize recursos em ferramentas que você não entende completamente.

Comentários
Comente só assim vamos crescer juntos!