Last active
March 9, 2017 07:23
-
-
Save jordanbtucker/40be224bf48f28e807d51ba56a50e45e to your computer and use it in GitHub Desktop.
odrive decrypt testing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The following code attempts to decrypt a filename encrypted by odrive. It | |
// fails when attempting to remove PKCS#7 padding from the plaintext. | |
const crypto = require('crypto') | |
// The original filename is `test.txt`. It was encrypted with odrive using the | |
// following password. | |
const password = 'password123' | |
const filename = 'MaUi8C8YFNhN5dzbjNtqgXx3Cm-PwyUYxR1Rl4JauHHrjrTMo0k9poE=' | |
// Information gathered from https://forum.odrive.com/t/encryption-questions-key-storage-decryption-process-and-others/2094/2 | |
const VERSION_SIZE = 1 | |
const SALT_SIZE = 64 / 8 | |
const BLOCK_SIZE = 128 / 8 | |
const HEADER_SIZE = VERSION_SIZE + SALT_SIZE + BLOCK_SIZE | |
const KDF_ITER = 5000 | |
const KEY_SIZE = 256 / 8 | |
const KDF_DIGEST = 'sha256' | |
const ENC_ALG = 'aes-256-cbc' | |
// Convert the URL-safe Base64 string to Base64. | |
const filenameBase64 = filename.replace(/-/g, '+').replace(/_/g, '/') | |
// Decode the Base64 string. | |
const data = Buffer.from(filenameBase64, 'base64') | |
console.log('data', data.toString('hex')) | |
// The first byte is an internal version number. | |
const version = data.slice(0, VERSION_SIZE) | |
// The next eight bytes is the salt. | |
const salt = data.slice(VERSION_SIZE, VERSION_SIZE + SALT_SIZE) | |
console.log('salt', salt.toString('hex')) | |
// The next eight bytes is the IV. | |
const iv = data.slice(VERSION_SIZE + SALT_SIZE, HEADER_SIZE) | |
console.log('iv', iv.toString('hex')) | |
// The remaining bytes is the ciphertext. | |
const ciphertext = data.slice(HEADER_SIZE, data.length) | |
console.log('ciphertext', ciphertext.toString('hex')) | |
// Use PBKDF2 with the password and salt to derive and encryption key. | |
const key = crypto.pbkdf2Sync(password, salt, KDF_ITER, KEY_SIZE, KDF_DIGEST) | |
console.log('key', key.toString('hex')) | |
// Use the key and IV to create an AES-256-CBC decryptor. | |
const decipher = crypto.createDecipheriv(ENC_ALG, key, iv) | |
// For testing, we've set the padding to false. Normally you'd set this to true | |
// or just leave this line out. | |
decipher.setAutoPadding(false) | |
// Decrypting the ciphertext. | |
const plaintext1 = decipher.update(ciphertext) | |
const plaintext2 = decipher.final() | |
const plaintext = Buffer.concat([plaintext1, plaintext2]) | |
console.log('plaintext', plaintext.toString('hex')) | |
// The plaintext should start with 0x00000000 and end with 0x04040404, but it | |
// doesn't in this case. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment