# How to decrypt flows_cred.json from NodeRED data ?

#### Published by HugoPoi on 28 December 202128 December 2021

## 1. Digging the code

The first step is to reverse the code from NodeRED, simple steps
1. Clone the sources
`git clone https://github.com/node-red/node-red.git`
2. Dig with grep in the code
`grep -ril crypto packages/`

       packages/node_modules/@node-red/editor-api/lib/auth/index.js
       packages/node_modules/@node-red/editor-api/lib/auth/strategies.js
       packages/node_modules/@node-red/editor-api/lib/auth/tokens.js
       packages/node_modules/@node-red/editor-api/lib/editor/comms.js
       packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js
       packages/node_modules/@node-red/editor-client/src/types/README.md
       packages/node_modules/@node-red/editor-client/src/types/node/crypto.d.ts
       packages/node_modules/@node-red/editor-client/src/types/node/tls.d.ts
       packages/node_modules/@node-red/editor-client/src/vendor/monaco/dist/editor.js
       packages/node_modules/@node-red/editor-client/src/vendor/monaco/dist/html.worker.js
       packages/node_modules/@node-red/editor-client/src/vendor/monaco/dist/ts.worker.js
       packages/node_modules/@node-red/nodes/core/common/60-link.js
       packages/node_modules/@node-red/nodes/core/network/21-httprequest.js
       packages/node_modules/@node-red/runtime/lib/nodes/credentials.js
       packages/node_modules/@node-red/runtime/lib/storage/index.js
       packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/git/authServer.js
       packages/node_modules/@node-red/runtime/lib/storage/localfilesystem/projects/index.js
       packages/node_modules/node-red/red.js

3. Find the interesting parts
   `packages/node_modules/@node-red/runtime/lib/nodes/credentials.js` file name looks promising.

    function decryptCredentials(key,credentials) {
        var creds = credentials["$"];
        var initVector = Buffer.from(creds.substring(0, 32),'hex');
        creds = creds.substring(32);
        var decipher = crypto.createDecipheriv(encryptionAlgorithm, key, initVector);
        var decrypted = decipher.update(creds, 'base64', 'utf8') + decipher.final('utf8');
        return JSON.parse(decrypted);
    }

and

                var defaultKey;
                try {
                    defaultKey = settings.get('_credentialSecret');
                } catch(err) {
                }
                if (defaultKey) {
                    defaultKey = crypto.createHash('sha256').update(defaultKey).digest();
                    encryptionKeyType = "system";
                }

and

                    // Check if we have a generated _credSecret to decrypt with and remove
                    if (defaultKey) {
                        log.debug("red/runtime/nodes/credentials.load : default key present. Will migrate");
                        if (credentialsEncrypted) {
                            try {
                                credentials = decryptCredentials(defaultKey,credentials)
                            } catch(err) {
                                credentials = {};
                                log.warn(log._("nodes.credentials.error",{message:err.toString()}))
                                var error = new Error("Failed to decrypt credentials");
                                error.code = "credentials_load_failed";
                                throw error;
                            }
                        }
                        dirty = true;
                        removeDefaultKey = true;
                    }

- The key come from `_credentialSecret` which is in the file `.config.runtime.json`
- Then the key is hashed as sha256 and pass to `decryptCredentials()` function
- `decryptCredentials()` extract the 32 first characters and taken them as the Initial Vector
- The end of creds string is a base64 encoded, and the content is encrypted aes

## 2. Openssl is a pain

The command `openssl enc -base64 -d` DOESN’T DO THE SAME AS `base64 -d`

Why ?

Because you need `-A` one line weird option.

`openssl enc -base64 -d -A` does the same as `base64 -d`

So if you need to decrypt a encoded base64 payload you need the -a and -A options like

`openssl enc -aes-256-ctr -d -a -A`

Our key is `jq -j '._credentialSecret' $1/.config.runtime.json | sha256sum | cut -c 1-64` ( pay attention to the `-j` option of `jq` command for not passing a breakline to sha256sum).

Our IV is `jq -r '.["$"]' $1/flows_cred.json | cut -c 1-32`.

And our aes data is `jq '.["$"]' -j $1/flows_cred.json | cut -c 33-`.

## 3. Final script

    #!/bin/bash
    #
    # Decrypt flows_cred.json from a NodeRED data directory
    #
    # Usage
    # ./node-red-decrypt-flows-cred.sh ./node_red_data
    #
    jq  '.["$"]' -j $1/flows_cred.json | \
      cut -c 33- | \
      openssl enc -aes-256-ctr -d -base64 -A -iv `jq  -r '.["$"]' $1/flows_cred.json | cut -c 1-32` -K `jq -j '._credentialSecret' $1/.config.runtime.json | sha256sum | cut -c 1-64`

Categories: News
Tags: Bash flows credential NodeRED Openssl

### 0 Comments

### Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Name *
Email *
Website
What's on your mind?

Δ

## Related Posts

###### News

#### Do a wifi repeater with only one wifi card and Debian

Summary I wanted to extend the range of an existing wifi access point without cables or changing the configuration. It’s a temporary installation, and I doesn’t want do buy more hardware and use what I Read more…

###### News

#### My shitty Nvidia DisplayPort Problems who no ones care about

Recently I have done the acquisition of a new ULTRAWIDE screen, precisily a Philips 439PH9 with a DisplayPort v1.4, this information is very important for what’s coming next. The problem The morning I receive it, Read more…

###### News

#### How to backup FreeNas zvol to S3 storage

Context I have a FreeNAS setup I want a cheap offsite backup solution Backblaze only offer S3 storage solution I have virtual machines on zvol to backup (not just files) ZFS send/receive is very convenient Read more…