1
votes

As per the docs in chef it uses a shared secret to encrypt data bag items.

Shared secret is created with:

openssl rand -base64 512 | tr -d '\r\n' > encrypted_data_bag_secret

And the data is saved with below format.

id:   mysql

pass:
cipher:         aes-256-cbc
encrypted_data: JZtwXpuq4Hf5ICcepJ1PGQohIyqjNX6JBc2DGpnL2WApzjAUG9SkSdv75TfKSjX4
iv:             VYY2qx9b4r3j0qZ7+RkKHg==
version:        1

user:
cipher:         aes-256-cbc
encrypted_data: 10BVoNb/plkvkrzVdybPgFFII5GThZ3Op9LNkwVeKpA=
iv:             uIqKHZ9skJlN2gpJoml6rQ==
version:        1

I was trying to decrypt one of the items using openssl but failing to get correct magic combination.

Using the above example data, the below is the best command i came up with that i think should work. The data is base64 decoded and from openssl man the iv and key should be in hex but i think think my conversions are feeding openssl with correct data.

cat 'JZtwXpuq4Hf5ICcepJ1PGQohIyqjNX6JBc2DGpnL2WApzjAUG9SkSdv75TfKSjX4' > encrypted_data
cat 'VYY2qx9b4r3j0qZ7+RkKHg==' > iv

openssl enc -d -aes-256-cbc -a \
  -in encrypted_data \
  -K $(cat encrypted_data_bag_secret|base64 -d|xxd -p) \
  -iv $(cat iv|base64 -d|xxd -p) 

Can anyone see what i'm doing wrong or have working example for manually decrypting chef data bag item with openssl and shared secret file ?

2
Do I even want to know why you are doing this?coderanger
I have to audit our chef servers... multiple that have drifted out of sync and i want to test the local git saved versions of the data bag files to see which have been encrypted using the 'common' secret key file.Flo Woo
Okay, so why not decrypt them using using Chef instead of a bash script and openssl?coderanger
since i'm referencing local .json i thought it would be easier to parse via jq and feed in the encrypted_data and iv key values to openssl to get simple success || fail. But i thought using openssl would have been much easier to plug in the values and profit.Flo Woo
knife -z data bag show is your friend :)coderanger

2 Answers

1
votes

To expand upon @coderanger:

Given an encrypted data bag's contents, you'll need to base64-decode both the iv and encrypted_data, then take the raw key value and run SHA256 on it. Here's an example Python script using the pass data bag item above:

import hashlib
from base64 import b64decode
from Crypto.Cipher import AES

iv = b64decode('VYY2qx9b4r3j0qZ7+RkKHg==')
key = 'data_bag_key_used_to_encrypt_data_bag'
key = hashlib.sha256(key.encode()).digest()
encoded = b64decode('JZtwXpuq4Hf5ICcepJ1PGQohIyqjNX6JBc2DGpnL2WApzjAUG9SkSdv75TfKSjX4')

dec = AES.new(key=key, mode=AES.MODE_CBC, IV=iv)
value = dec.decrypt(encoded)

value should now contain your decrypted data_bag contents

0
votes

Run the key data through SHA256, and make sure you use the raw digest, not in hex or base64. You also don't want to be base64-decode it first, we generate the key in base64 mode just so it only uses printable characters, not because it is ever used as base64 data.

You can see the relevant code in the encryptor class.

Also keep in mind this will only work for version 1 bag items. We also have version 2 which adds a MAC you would have to strip off, and version 3 which uses aes-256-gcm instead.