Pool encryption dataset

Hi guys,
when I do configuration export with pools secret, then I get zip file.
In that zip file are 2 files: pwenc_secret and freenas-v1.db.
In that db file is table named “storage_encrypteddataset”.
There are saved passwords for those pools. Are those encryption keys encoded or those are plain text passwords?

Those are encrypted keystrings.

When combined with pwenc_secret, they are decrypted to reveal the real keystrings needed to unlock your datasets during bootup.

Passphrases are never saved in your config file. They must be memorized. Keystrings (when you use a “key” encryption for a dataset) are saved in a scrambled form in your config.

Thank you, do you know how I can decrypt that keystring?

Just export the encryption keys from within TrueNAS GUI. Why create extra work for yourself?

1 Like

Is there possibility to do it from CLI?

I still don’t know why you want to. Exporting the dataset encryption keys will result with the same keystrings.

Here is a modified python script, sourced from Robert Milkowski. It basically borrows from the middleware:

decode_key.py
#!/usr/bin/python3

# based on /usr/lib/migrate113/freenasUI/system/migrations/0022_cloud_sync.py

import sys
import base64
from Cryptodome.Cipher import AES
import sqlite3


PWENC_BLOCK_SIZE = 32
PWENC_FILE_SECRET = 'pwenc_secret'
PWENC_PADDING = b'{'


def pwenc_get_secret():
    with open(PWENC_FILE_SECRET, 'rb') as f:
        secret = f.read()
    return secret


def pwenc_decrypt(encrypted=None):
    if not encrypted:
        return ""
    from Cryptodome.Util import Counter
    encrypted = base64.b64decode(encrypted)
    nonce = encrypted[:8]
    encrypted = encrypted[8:]
    cipher = AES.new(
        pwenc_get_secret(),
        AES.MODE_CTR,
        counter=Counter.new(64, prefix=nonce),
    )
    return cipher.decrypt(encrypted).rstrip(PWENC_PADDING).decode('utf8')


if len(sys.argv) == 2:
    print(pwenc_decrypt(sys.argv[1]))
    exit(0)

dbcon = sqlite3.connect('freenas-v1.db')
dbcur = dbcon.cursor()
for row in dbcur.execute('select * from storage_encrypteddataset'):
    ds_id, ds_name, ds_enc_key, kmip_enc_key = row
    #print(ds_id, ds_name, ds_enc_key, pwenc_decrypt(ds_enc_key))
    print(f'dataset: {ds_name}\n  key: {pwenc_decrypt(ds_enc_key)}\n')

All three files must exist in the same directory for this to work:

  • decode_key.py
  • freenas-v1.db
  • pwenc_secret

I made a couple modifications so that it can be run locally with exported config files, without having to run it on a live TrueNAS system. Just put all three files in the same folder.

1 Like

Thank you Winnielinnie,

you script was working. Although I wasn’t able to get it run on Truenas.
I have python already installed on my Windows PC. Had to just add C++ build tools from MS Visual Studio. Than was able to install PyCryptodome and decrypt those secrets.