Skip to content

Instantly share code, notes, and snippets.

@frederickding
Created March 15, 2026 00:09
Show Gist options
  • Select an option

  • Save frederickding/195f4176543db5d6506bc5e6dd299dc6 to your computer and use it in GitHub Desktop.

Select an option

Save frederickding/195f4176543db5d6506bc5e6dd299dc6 to your computer and use it in GitHub Desktop.
Extract SED passwords and global SED password from TrueNAS SCALE backup

Requirements

  • Backup from TrueNAS SCALE in .tar format, extracted
  • Must have password seed backed up, named as pwenc_secret
  • SQLite database from .tar should be named freenas-v1.db

Dependencies

  • Python 3.14+
  • pycryptodome >=3.23.0, <4.0.0
#!/usr/bin/env python3
import base64
import sys
import sqlite3
from Crypto.Cipher import AES
from Crypto.Util import Counter
def main(argv):
aes_key = read_aes_key()
keys = load_encrypted_keys()
for disk_serial, encrypted_key in keys.items():
decrypted = decrypt(encrypted_key, aes_key)
print(disk_serial)
print(decrypted)
print()
return 0
def read_aes_key():
with open('pwenc_secret', 'rb') as f:
return f.read()
def load_encrypted_keys():
d = {}
with sqlite3.connect('freenas-v1.db') as conn:
for row in conn.execute('SELECT adv_sed_passwd FROM system_advanced'):
d["defaultsedpassword"] = row[0]
for row in conn.execute('SELECT disk_serial, disk_passwd FROM storage_disk'):
d[row[0]] = row[1]
return d
def decrypt(encrypted, key):
if not encrypted:
return ''
encrypted = base64.b64decode(encrypted)
nonce = encrypted[:8]
encrypted = encrypted[8:]
cipher = AES.new(key, AES.MODE_CTR, counter=Counter.new(64, prefix=nonce))
return cipher.decrypt(encrypted).rstrip(b'{').decode('utf8')
if __name__ == '__main__':
sys.exit(main(sys.argv))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment