Reverse Engineering Rekordbox OneLibrary / Device Library Plus exportLibrary.db SQLCipher Encryption + Key
Some notes on Pioneer / AlphaTheta Rekordbox OneLibrary and Device Library Plus exportLibrary.db SQLCipher encryption, key obfuscation, and related master.db / etc context.
exportLibrary.dbuses XOR with obfuscated blob, then Base85 to obscure the keyexportLibrary.dbobfuscated blob XOR key: https://github.com/search?q=%22657f48f84c437cc1%22&type=codeexportLibrary.dbobfuscated blob: https://github.com/search?q=%22PN_1dH8%24oLJY%22&type=codeexportLibrary.dbkey: https://github.com/search?q=%22r8gddnr4k847830ar6cqzbkk0el6qytmb3trbbx805jm74vez64i5o8fnrqryqls%22&type=code
master.dbkey: https://github.com/search?q=%22402fd482c38817c35ffa8ffb8c7d93143b749e7d315df7a81732a1ff43608497%22&type=code- https://github.com/sqlcipher/sqlcipher
-
SQLCipher
-
SQLCipher is a standalone fork of SQLite that adds 256 bit AES encryption of database files and other security features.
- https://www.zetetic.net/sqlcipher/
-
- https://alphatheta.com/en/onelibrary/
-
OneLibrary
-
OneLibrary is a music library format that takes essential DJ performance data – including playlists, cue points, and beatgrids and makes it work across different types of DJ software and hardware from multiple brands.
-
We’re working with other brands to create a world where you can use your music libraries – your creative assets – freely on any type of media or device (file-based music, cloud, streaming, USB, PC, mobile, etc.) and hardware, regardless of the DJ software you use.
-
- https://www.lexicondj.com/blog/everything-you-need-to-know-about-device-library-plus-and-more
-
Everything You Need To Know About Device Library Plus (Dec 21st 2023)
-
What is Pioneer's Device Library Plus and why does it matter?
-
Device Library Plus is the exportLibrary.db file on your USB. Just like the main Rekordbox database, it is an encrypted SQLite database. it is a separate file that lives next to the old Device Library database.
-
Normally I would go into detail a bit more about the database file, but it is encrypted and this time I don't have the encryption key so I can't access it. It is probably similar in structure to the main Rekordbox database, and it contains your track info, cues, playlists and more.
-
- mixxxdj/mixxx#15556
-
Issue 15556: Add OneLibrary support
-
- xsco/libdjinterop#177
-
Issue 177: Add OneLibrary support
-
- https://github.com/morizkraemer/fourfour/blob/master/pioneer-usb-writer/reference-code/PIONEER.md
-
Pioneer DeviceSQL & ANLZ Format — Reverse Engineering Notes
-
This document contains technical discoveries about Pioneer's proprietary DeviceSQL format (export.pdb), ANLZ analysis files, and the newer OneLibrary format (exportLibrary.db) that are not publicly documented. These findings were obtained through binary analysis, disassembly, and hardware testing on a CDJ-3000 (firmware 3.19).
Existing open-source documentation (Deep Symmetry, rekordcrate, Kaitai Struct specs) covers the broad structure. This document focuses on the undocumented details that make or break hardware compatibility — the things that cause "rekordbox database not found" or silent re-analysis on real players.
- https://github.com/morizkraemer/fourfour/blob/master/pioneer-usb-writer/reference-code/PIONEER.md#9-onelibrary-format-exportlibrarydb
-
- OneLibrary Format (exportLibrary.db)
OneLibrary (formerly "Device Library Plus") is a new export format introduced in rekordbox 6.8+ and expanded in rekordbox 7.x. It replaces the binary DeviceSQL format (
export.pdb) with an encrypted SQLite database for newer hardware. The format was developed by AlphaTheta and adopted by Algoriddim (djay Pro) and Native Instruments (Traktor) for cross-platform DJ library interoperability. -
The database is encrypted with SQLCipher (SQLite encryption extension). The key is different from the
master.dbkey. -
Decryption key:
r8gddnr4k847830ar6cqzbkk0el6qytmb3trbbx805jm74vez64i5o8fnrqryqls -
The key is derived from an obfuscated constant in the rekordbox binary
-
-
- https://github.com/dylanljones/pyrekordbox
-
Pyrekordbox is a Python package for interacting with the library and export data of Pioneers Rekordbox DJ Software.
-
https://github.com/dylanljones/pyrekordbox/blob/master/docs/source/formats/devicelib_plus.md
-
Rekordbox Device Library Plus Format
-
Similar to the main database of Rekordbox (
master.db), the Device Library Plus is a SQLite database encrypted via the SQLCipher library. Luckily, it appears that the key of the database is not license or machine dependent and all Device Libraries are encrypted with the same key. -
The database schema is similar to the main Rekordbox database. It contains a selection of tables from the main database, with similar columns and data types.
-
-
https://github.com/dylanljones/pyrekordbox/blob/master/docs/source/key.md
-
Database key
-
If the automatic key extraction fails the command line interface of pyrekordbox provides a command for downloading the key from known sources and writing it to the cache file
-
Once the key is cached the database can be opened without providing the key. if you obtained the key from another source, you can also pass it to the database handler
-
On MacOS, the key can be extracted using the RekordLocksmith tool
- https://github.com/Bide-UK/rekordlocksmith
-
RekordLocksmith
-
This tool was developed with the ethos that users should have unfettered access to their own music libraries. If you're looking to make changes to your Rekordbox library, you shouldn't have to navigate through intentionally placed barriers such as encrypted databases and obfuscated keys.
-
- https://github.com/Bide-UK/rekordlocksmith
-
-
GitHub Copilot (GPT 5.4) Repo Exploration RE: DB Encryption Methods and Keys
How does this project handle the SQLCipher encryption on the main master.db and device library plus exportLibrary.db ? Where does it get the key for them from? EtcIt uses SQLCipher directly via Python, and for the keys it does not derive them from the database files themselves. It either uses a built-in/deobfuscated known key or a cached/user-supplied key, depending on which database you mean.
master.db: opened throughsqlcipher3+ SQLAlchemy pysqlcipher dialect.- If you don’t pass a key,
pyrekordboxsays it will automatically read/use the Rekordbox DB key. - In the current code path, the actual unlock call uses
deobfuscate(BLOB)when no key is provided. - The docs/changelog also mention a cached key mechanism and a
download-keyCLI fallback for cases where automatic extraction fails.
- If you don’t pass a key,
- Device Library Plus /
exportLibrary.db: also opened through SQLCipher.- If you don’t pass a key, it uses a known built-in key via
deobfuscate(BLOB). - The docs explicitly say this device/export DB key appears to be shared across all Device Library Plus databases, not machine/license dependent.
- If you don’t pass a key, it uses a known built-in key via
- I did not find a separate implementation specifically for a plain “device library” beyond the newer Device Library Plus /
exportLibrary.dbsupport in the returned results. - I also did not find evidence in the returned results of custom raw
PRAGMA key=...handling; instead it passes the key in the SQLAlchemy SQLCipher connection URL.
For both DB types, the project imports
sqlcipher3if available:if unlock: if not _sqlcipher_available: # pragma: no cover raise ImportError("Could not unlock database: 'sqlcipher3' package not found") if not key: # pragma: no cover key = deobfuscate(BLOB) elif not key.startswith("402fd"): # Check if key looks like a valid key raise ValueError("The provided database key doesn't look valid!") # Unlock database and create engine logger.debug("Key: %s", key) url = f"sqlite+pysqlcipher://:{key}@/{db_path}?" engine = create_engine(url, module=sqlite3)
And similarly for Device Library Plus:
if unlock: if not _sqlcipher_available: # pragma: no cover raise ImportError("Could not unlock database: 'sqlcipher3' package not found") if not key: # pragma: no cover key = deobfuscate(BLOB) elif not key.startswith("r8gd"): # Check if key looks like a valid key raise ValueError("The provided database key doesn't look valid!") # Unlock database and create engine logger.debug("Key: %s", key) url = f"sqlite+pysqlcipher://:{key}@/{db_path}?" engine = create_engine(url, module=sqlite3)
So the practical mechanism is:
- import SQLCipher-capable sqlite driver (
sqlcipher3) - obtain key
- create SQLAlchemy engine with
sqlite+pysqlcipher://:{key}@/{db_path}?
The docs say the key is automatically read from Rekordbox config / extracted, and if that fails there are fallback paths.
The class docstring says:
key : str, optional The database key. By default, pyrekordbox automatically reads the database key from the Rekordbox v6 configuration file. This parameter is only required if the key extraction fails.
But the constructor unlock snippet currently shown in search results falls back to
deobfuscate(BLOB)ifkeyis empty.The project docs also document explicit fallback behavior:
# Database key If the automatic key extraction fails the command line interface of ``pyrekordbox`` provides a command for downloading the key from known sources and writing it to the cache file: ````shell python -m pyrekordbox download-key
Once the key is cached the database can be opened without providing the key. if you obtained the key from another source, you can also pass it to the database handler
db = Rekordbox6Database(key="<insert key here>")
or write it to the cache file manually:
from pyrekordbox.config import write_db6_key_cache write_db6_key_cache("<insert key here>") # call once db = Rekordbox6Database()
And the changelog clarifies the history: ```markdown name=CHANGELOG.md url=https://github.com/dylanljones/pyrekordbox/blob/f695541827cc488af267d6ca8a8e0052598d85a0/CHANGELOG.md#L377-L406 - **add CLI command to download and cache the RB6 db key from the web ([#64](https://github.com/dylanljones/pyrekordbox/issues/64))** Pyrekordbox tries to download the key from projects that have hard-coded the key (see issue [#77](https://github.com/dylanljones/pyrekordbox/issues/77)). If the download was successful it writes it to the cache file. - **add method for writing the RB6 db key cache manually ([#64](https://github.com/dylanljones/pyrekordbox/issues/64))** If the extraction of the Rekordbox database key fails (>=6.6.5), the user can now write the key manually to the cache file. After updating the cache the database can be opened without providing the key as argument. To make this work pyrekordbox now caches the decrypted key, not the password for decrypting the key.So for
master.db, the project’s model seems to be:- historically/ideally: extract key from local Rekordbox install/config
- if that fails: use cached decrypted key
- if that’s absent: user can
- pass the key manually,
- write it to cache manually,
- or use
download-keyto fetch from known external sources
The docs also describe manual extraction from the Rekordbox executable by breaking on
sqlite3_key_v2, which confirms the project assumes the real SQLCipher key is present in memory on the local machine:6. Click in the disassembly window, then press Ctrl+G to open the Go To Expression box, and search for `sqlite3_key_v2` and press OK. ... 11. The dump at the bottom left will move to that address... You should now see the key as a string.
The documentation is much more explicit here:
# Rekordbox Device Library Plus Format ... Similar to the main database of Rekordbox (``master.db``), the Device Library Plus is a SQLite database encrypted via the [SQLCipher](https://www.zetetic.net/sqlcipher/) library. Luckily, it appears that the key of the database is not license or machine dependent and all Device Libraries are encrypted with the same key.
And the code uses
deobfuscate(BLOB)by default, unless you pass a key explicitly, and it validates that user-supplied keys “look like” the expected format by checking they start withr8gd.So for
exportLibrary.db, the answer is basically:- pyrekordbox uses a known shared key
- that key is stored in obfuscated form in the project and recovered with
deobfuscate(BLOB) - user can override it by passing
key=...
According to the project docs:
master.db: docs say it “appears” not to be machine/license dependent.- Device Library Plus /
exportLibrary.db: docs explicitly say all such device libraries appear to use the same key.
For
master.db:## Encryption The new SQLite database is encrypted which means it can't be used without the encryption key. ... It appears that the key is not license or machine dependent and all databases are encrypted with the same keyThere seems to be a bit of tension between:
- the docstring/docs saying
master.dbkey is automatically read from Rekordbox config/extraction/cache, and - the constructor snippet showing default fallback directly to
deobfuscate(BLOB).
That suggests one of:
- the actual
BLOBmay itself be sourced from another module/config path, - the docs lag the code somewhat,
- or the search results didn’t include all surrounding imports/constants/helpers.
I don’t want to overstate that without reading the exact definitions of
BLOB,deobfuscate, and the config helpers.- A distinct older “device library” SQLCipher path separate from Device Library Plus /
exportLibrary.db - The exact source definition of
BLOB - The exact implementation of
deobfuscate - The exact cache file location/format from the snippets returned
Code search results are limited and may be incomplete. You can inspect more here:
- https://github.com/search?q=repo%3Adylanljones%2Fpyrekordbox+%28deobfuscate+OR+BLOB+OR+download-key+OR+write_db6_key_cache+OR+sqlite3_key_v2%29&type=code
- https://github.com/search?q=repo%3Adylanljones%2Fpyrekordbox+%28sqlcipher+OR+master.db+OR+exportLibrary.db+OR+%22PRAGMA+key%22%29&type=code
If you want, I can do a deeper pass and trace:
- where
BLOBis defined, - how
deobfuscate()works, - where the cached
master.dbkey is stored, - and whether the repo currently hardcodes the actual SQLCipher keys or reconstructs them indirectly.
-
- https://github.com/chrisle/alphatheta-connect
-
prolink-connect
-
A Typescript / JavaScript library that is able to talk to AlphaTheta ProDJLink enabled DJ equipment
-
AlphaTheta's PRO DJ LINK protocol, unlocked. Consume CDJ states + Retrieve complete track metadata.
-
GitHub Copilot (GPT 5.4) Repo Exploration RE: DB Encryption Methods and Keys
How does this project handle the SQLCipher encryption on the main master.db and device library plus exportLibrary.db ? Where does it get the key for them from? EtcIt delegates the SQLCipher handling for
exportLibrary.dbto the externalonelibrary-connectpackage; this repo itself does not appear to implement the decryption logic or derive the key locally.What I found:
alphatheta-connectadded OneLibrary /exportLibrary.dbsupport with SQLCipher encryption in v0.15.0.- When loading OneLibrary, it:
- fetches
PIONEER/rekordbox/exportLibrary.dbfrom the device over NFS, - writes it to a temp file,
- opens it via
new OneLibraryAdapter(tempFile).
- fetches
- The project re-exports
getEncryptionKey,openOneLibraryDb, andOneLibraryAdapterdirectly fromonelibrary-connect, which strongly suggests the actual SQLCipher open/key logic lives there, not here. - I did not find code in this repo that:
- issues
PRAGMA key, - computes the SQLCipher key,
- references
master.db, - references
device libraryby that name, - or directly manipulates SQLCipher settings.
- issues
Key evidence:
/** * Try to load OneLibrary database (exportLibrary.db). */ #tryLoadOneLibrary = async ( device: Device, slot: DatabaseSlot, tx: Telemetry.TelemetrySpan ): Promise<{adapter: OneLibraryAdapter; tempFile: string} | null> => { const oneLibraryPath = 'PIONEER/rekordbox/exportLibrary.db'; try { const dbData = await this.#fetchFileWithFallback(device, slot, oneLibraryPath, tx); const tempDir = os.tmpdir(); const tempFile = path.join(tempDir, `prolink-onelibrary-${device.id}-${slot}-${Date.now()}.db`); fs.writeFileSync(tempFile, dbData); const adapter = new OneLibraryAdapter(tempFile); return {adapter, tempFile}; } catch { return null; } };
/** * OneLibrary Database Adapter * * Re-exports from onelibrary-connect for backward compatibility. */ export { getEncryptionKey, openOneLibraryDb, OneLibraryAdapter, } from 'onelibrary-connect';
/** * Re-exports from onelibrary-connect */ export { getEncryptionKey, openOneLibraryDb, OneLibraryAdapter, } from 'onelibrary-connect';
"dependencies": { "@types/better-sqlite3": "^7.6.13", "@types/lodash": "^4.17.21", "@types/node": "^22.15.29", "@types/promise-retry": "^1.1.6", "@types/promise-timeout": "^1.3.3", "@types/signale": "^1.4.7", "async-mutex": "^0.5.0", "better-sqlite3-multiple-ciphers": "^12.5.0", "iconv-lite": "^0.6.3", "ip-address": "^10.1.0", "js-xdr": "^3.1.2", "kaitai-struct": "^0.11.0", "lodash": "^4.17.21", "lru_map": "^0.4.1", "metadata-connect": "file:../metadata-connect", "onelibrary-connect": "file:../onelibrary-connect",
### Added - **Passive monitoring mode**: Monitor Pro DJ Link networks via packet capture (pcap) without joining the network as a virtual CDJ. Allows monitoring alongside rekordbox. - **Artwork extraction from audio files via NFS**: Extract album artwork directly from audio files (MP3, FLAC, AIFF, M4A) over NFS when artwork is not available in the rekordbox database. - **OneLibrary database support**: Full support for rekordbox 7.x's new OneLibrary format (exportLibrary.db) with SQLCipher encryption, including tracks, playlists, cues, hot cue banks, myTags, and history.
- **OneLibrary Support** *(new)* - Full support for rekordbox 7.x's new OneLibrary format (exportLibrary.db) with SQLCipher encryption, including tracks, playlists, cues, hot cue banks, myTags, and history.
From this repo alone: not visible. The only concrete signal is that it re-exports:
getEncryptionKeyopenOneLibraryDbOneLibraryAdapter
from
onelibrary-connect, so the key derivation/retrieval is almost certainly implemented there.I don’t see handling for those in this repository.
This repo appears to support two DB paths/formats:
- Legacy device export DB:
PIONEER/rekordbox/export.pdb- parsed directly as Pioneer’s PDB format, not SQLCipher.
- OneLibrary DB:
PIONEER/rekordbox/exportLibrary.db- opened through
OneLibraryAdapter, which likely handles SQLCipher.
- opened through
For comparison, the fallback legacy path is explicit here:
/** * Load PDB database (export.pdb) and hydrate into MetadataORM. */ #loadPdbDatabase = async ( device: Device, slot: DatabaseSlot, tx: Telemetry.TelemetrySpan ): Promise<MetadataORM> => { const pdbPath = 'PIONEER/rekordbox/export.pdb'; const pdbData = await this.#fetchFileWithFallback(device, slot, pdbPath, tx); const dbCreateTx = tx.startChild({op: 'setupDatabase'}); const orm = new MetadataORM(); dbCreateTx.finish(); await hydrateDatabase({ orm, pdbData, span: tx, onProgress: progress => this.#emitter.emit('hydrationProgress', {device, slot, progress}), }); return orm; };
So, in short:
exportLibrary.db: SQLCipher, but handled indirectly throughonelibrary-connect.export.pdb: not SQLCipher; parsed directly.master.db: no evidence in this repo.- “device library”: no separate SQLCipher handling visible here beyond
exportLibrary.db.
The code search results I used may be incomplete because search responses are limited to 10 results. To inspect more matches in GitHub UI, use:
- https://github.com/search?q=repo%3Achrisle%2Falphatheta-connect+sqlcipher&type=code
- https://github.com/search?q=repo%3Achrisle%2Falphatheta-connect+exportLibrary.db&type=code
- https://github.com/search?q=repo%3Achrisle%2Falphatheta-connect+getEncryptionKey&type=code
- https://github.com/search?q=repo%3Achrisle%2Falphatheta-connect+master.db&type=code
If you want, I can next trace the likely key source by inspecting the sibling/dependency repo
onelibrary-connectand tell you exactly howgetEncryptionKey()works.
-
- https://github.com/chrisle/onelibrary-connect
-
Read and query rekordbox OneLibrary (exportLibrary.db) SQLCipher databases from Pioneer DJ devices
-
GitHub Copilot (GPT 5.4) Repo Exploration RE: DB Encryption Methods and Keys
How does this project handle the SQLCipher encryption on the main master.db and device library plus exportLibrary.db ? Where does it get the key for them from? EtcThis project does not fetch SQLCipher keys from the device, OS, user config, or the databases themselves. It uses one hardcoded deobfuscation routine to derive a single built-in SQLCipher key, then applies that key whenever it opens a OneLibrary database.
- Encryption mode: SQLCipher, with
legacy = 4 - Key source: a hardcoded obfuscated blob in
src/encryption.ts - How key is derived: base85 decode → XOR with fixed bytes → zlib inflate
- Where applied:
src/connection.tsvia SQLCipher pragmas - Which DBs this repo actually supports: the code appears to target OneLibrary /
exportLibrary.db-style databases, not a separate implementation formaster.db
openOneLibraryDb()is the central DB open path:/** * OneLibrary Database Connection */ import Database from 'better-sqlite3-multiple-ciphers'; import {getEncryptionKey} from './encryption.js'; /** * Open a OneLibrary database with SQLCipher decryption */ export function openOneLibraryDb(dbPath: string): Database.Database { const key = getEncryptionKey(); const db = new Database(dbPath, {readonly: true}); db.pragma('cipher = sqlcipher'); db.pragma('legacy = 4'); db.pragma(`key = '${key}'`); return db; }
What this means:
- it uses
better-sqlite3-multiple-ciphers - opens the DB read-only
- explicitly selects SQLCipher
- sets
legacy = 4 - then sets the SQLCipher key with
PRAGMA key
So the project’s entire encryption handling is basically: derive static key, set SQLCipher pragmas, query normally.
The key derivation is all in
src/encryption.ts:/** * OneLibrary Database Encryption * * The database is encrypted with SQLCipher 4. The encryption key is derived from * a hardcoded obfuscated blob. */ import * as zlib from 'zlib'; /** * The obfuscated encryption key blob from pyrekordbox */ const BLOB = Buffer.from( 'PN_1dH8$oLJY)16j_RvM6qphWw`476>;C1cWmI#se(PG`j}~xAjlufj?`#0i{;=glh(SkW)y0>n?YEiD`l%t(', 'ascii' ); /** * XOR key used for deobfuscation */ const BLOB_KEY = Buffer.from('657f48f84c437cc1', 'ascii'); /** * Base85 (RFC 1924) decode */ function base85Decode(input: Buffer): Buffer { const alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~'; const charToValue = new Map<string, number>(); for (let i = 0; i < alphabet.length; i++) { charToValue.set(alphabet[i], i); } const inputStr = input.toString('ascii'); const result: number[] = []; for (let i = 0; i < inputStr.length; i += 5) { const chunk = inputStr.slice(i, i + 5); let value = 0; for (const char of chunk) { const v = charToValue.get(char); if (v === undefined) { throw new Error(`Invalid base85 character: ${char}`); } value = value * 85 + v; } const bytes = [ (value >> 24) & 0xff, (value >> 16) & 0xff, (value >> 8) & 0xff, value & 0xff, ]; const numBytes = chunk.length === 5 ? 4 : chunk.length - 1; result.push(...bytes.slice(0, numBytes)); } return Buffer.from(result); } /** * Deobfuscate the blob to get the encryption key */ function deobfuscate(blob: Buffer): string { const decoded = base85Decode(blob); const xored = Buffer.alloc(decoded.length); for (let i = 0; i < decoded.length; i++) { xored[i] = decoded[i] ^ BLOB_KEY[i % BLOB_KEY.length]; } const decompressed = zlib.inflateSync(xored); return decompressed.toString('utf-8'); } /** * Get the SQLCipher encryption key for OneLibrary databases */ export function getEncryptionKey(): string { const key = deobfuscate(BLOB); if (!key.startsWith('r8gd')) { throw new Error('Invalid encryption key derived'); } return key; }
So the repo is doing this:
- start with a hardcoded ASCII blob
- decode it as RFC1924 base85
- XOR the bytes with a repeating fixed ASCII key:
657f48f84c437cc1 - inflate the result with zlib
- treat the final UTF-8 text as the SQLCipher key
- sanity-check that it starts with
r8gd
No, not in this repo.
I did not find code that:
- extracts a key from device metadata
- negotiates a key with hardware
- reads a key from
propertyor another table - derives per-device keys
- prompts the user for a password
- reads env vars or config files for the key
Instead, the repo comment says the blob is “from pyrekordbox”, so the implementation is essentially reusing known reverse-engineered knowledge.
Based on the code present, the project does not have separate encryption logic for different database types.
What I found:
- The package description says it reads OneLibrary (
exportLibrary.db) SQLCipher databases OneLibraryAdapteralways usesopenOneLibraryDb(dbPath)openOneLibraryDb()always uses the same static key flow- The schema includes fields like
masterDbId/masterContentId, but those are just schema fields, not evidence of opening a separatemaster.db
For example:
kuvoDeliveryComment: string | null; // rekordbox sync masterDbId: number | null; masterContentId: number | null; analysisDataFilePath: number | null; analysedBits: number | null; contentLink: number | null;
Those
masterDbIdreferences are just columns in the DB schema, not key-management logic.exportLibrary.db: explicitly supported, opened with the built-in SQLCipher key- device library DB: if it is the same OneLibrary/SQLCipher format, this code would appear to treat it the same way
master.db: I do not see dedicated support or separate handling in this repo
The adapter and comments consistently frame this as OneLibrary / exportLibrary.db support:
/** * OneLibrary Database Adapter * * Provides an interface for reading the OneLibrary (exportLibrary.db) SQLite database * used by modern rekordbox versions and Pioneer DJ devices. */
and:
{ "name": "onelibrary-connect", "version": "1.0.0", "description": "Read and query rekordbox OneLibrary (exportLibrary.db) SQLCipher databases from Pioneer DJ devices", ... }So I would not conclude from this repo alone that it fully implements all variants of:
- desktop rekordbox
master.db - device-side library db
- exported
exportLibrary.db
Instead, I’d conclude it assumes the same known SQLCipher key works for the OneLibrary DBs it targets.
The code uses:
const db = new Database(dbPath, {readonly: true}); db.pragma('cipher = sqlcipher'); db.pragma('legacy = 4'); db.pragma(`key = '${key}'`);
This suggests the author expects the DB format to be compatible with SQLCipher’s “legacy 4” setting in
better-sqlite3-multiple-ciphers. In practice, that’s a compatibility setting needed to open these DBs correctly with that binding.The project handles encryption in a very simple, centralized way:
- it assumes the DB is SQLCipher-encrypted
- it derives one static key from an obfuscated constant
- it configures the SQLite binding for SQLCipher and
legacy = 4 - it uses that same flow for every DB connection it opens
It does not appear to:
- discover keys dynamically
- use per-device/per-user secrets
- have separate decryption routines for
master.dbvsexportLibrary.db
“How does this project handle the SQLCipher encryption on the main master.db and device library plus exportLibrary.db?”
It only visibly implements one decryption path:
openOneLibraryDb(). That path applies SQLCipher pragmas and a single derived key. The repository is explicitly built around OneLibrary /exportLibrary.db. I do not see dedicatedmaster.dbhandling.From a hardcoded obfuscated blob in
src/encryption.ts, deobfuscated locally in code. Not from the device, not from user input, not from a remote service.If you want, I can next:
- extract the actual derived key value from the code path, or
- compare this repo’s approach to
pyrekordboxand explain whether the same key likely applies tomaster.dbtoo.
- Encryption mode: SQLCipher, with
-
- https://github.com/liamcottle/pioneer-rekordbox-database-encryption
-
PioneerDJ Rekordbox Database Decryption
-
Rekordbox v6 has an encrypted master.db database file. The database file is encrypted with sqlcipher.
-
- https://github.com/0xdevalias
- https://gist.github.com/0xdevalias
- https://github.com/0xdevalias/chatgpt-source-watch : Analyzing the evolution of ChatGPT's codebase through time with curated archives and scripts.
- Deobfuscating / Unminifying Obfuscated Web App Code (0xdevalias' gist)
- Reverse Engineering Webpack Apps (0xdevalias' gist)
- React Server Components, Next.js v13+, and Webpack: Notes on Streaming Wire Format (
__next_f, etc) (0xdevalias' gist)) - Fingerprinting Minified JavaScript Libraries / AST Fingerprinting / Source Code Similarity / Etc (0xdevalias' gist)
- Bypassing Cloudflare, Akamai, etc (0xdevalias' gist)
- Debugging Electron Apps (and related memory issues) (0xdevalias' gist)
- devalias' Beeper CSS Hacks (0xdevalias' gist)
- Reverse Engineering Golang (0xdevalias' gist)
- Reverse Engineering on macOS (0xdevalias' gist)