Skip to content

bitcoin2john.py: SQLite3 format support #5770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: bleeding-jumbo
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ Major changes from 1.9.0-jumbo-1 (May 2019) in this bleeding-edge version:
project in August 2020 by supporting (and distinguishing) both our meaning
(bcrypt-pbkdf + AES-256-CTR) and theirs (MD5 + single DES). [Solar; 2025]

- bitcoin2john.py: add support SQLite3 format [Maxim Kuleshov; 2025]


Major changes from 1.8.0-jumbo-1 (December 2014) to 1.9.0-jumbo-1 (May 2019):

Expand Down
3 changes: 3 additions & 0 deletions doc/README.bitcoin
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ This procedure also works with many altcoins historically forked from Bitcoin.

The bitcoin2john.py script is compatible with both Python 2 and Python 3.

Bitcoin Core 0.21.0 and above uses SQLite3 for new wallets. In this case,
Berkeley DB support is not required.

Since Python 3 no longer provides Berkeley DB support out of the box, to get
the script to work with Python 3 you need to install the corresponding module:

Expand Down
57 changes: 44 additions & 13 deletions run/bitcoin2john.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# Copyright (c) 2012-2018 Dhiru Kholia <dhiru at openwall.com>
# Copyright (c) 2019 Solar Designer
# Copyright (c) 2019 exploide
# Copyright (c) 2025 Maxim Kuleshov <[email protected]>
# Redistribution and use in source and binary forms, with or without
# modification, are permitted. (This is a heavily cut-down "BSD license".)
#
Expand All @@ -30,16 +31,24 @@
import logging
import struct
import sys
import sqlite3

try:
from bsddb.db import *
except:
try:
from bsddb3.db import *
except:
sys.stderr.write("Error: This script needs bsddb3 to be installed!\n")
sys.exit(1)

bsddb_db = None

def do_import_bsddb():
global bsddb_db
if bsddb_db is not None:
return

try:
import bsddb.db as bsddb_db
except:
try:
import bsddb3.db as bsddb_db
except:
sys.stderr.write("Error: This script needs bsddb3 to be installed!\n")
sys.exit(1)

json_db = {}

Expand Down Expand Up @@ -114,13 +123,35 @@ def _read_num(self, format):
self.read_cursor += struct.calcsize(format)
return i

class Sqlite3DB:
def __init__(self, walletfile):
self.cx = sqlite3.connect(walletfile)

def is_sqlite3(self):
try:
self.cx.execute("PRAGMA quick_check")
return True
except sqlite3.DatabaseError:
return False

def close(self):
self.cx.close()

def items(self):
return list(self.cx.execute('SELECT key,value FROM main'))

def open_wallet(walletfile):
db = DB()
DB_TYPEOPEN = DB_RDONLY
flags = DB_THREAD | DB_TYPEOPEN
db = Sqlite3DB(walletfile)
if db.is_sqlite3():
return db

do_import_bsddb()
db = bsddb_db.DB()
DB_TYPEOPEN = bsddb_db.DB_RDONLY
flags = bsddb_db.DB_THREAD | DB_TYPEOPEN
try:
r = db.open(walletfile, "main", DB_BTREE, flags)
except DBError as e:
r = db.open(walletfile, "main", bsddb_db.DB_BTREE, flags)
except bsddb_db.DBError as e:
logging.error(e)
r = True

Expand Down