Skip to content

Instantly share code, notes, and snippets.

@danilvalov
Created February 22, 2024 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danilvalov/2044c22be3c64ab0ce17d4bc853bae64 to your computer and use it in GitHub Desktop.
Save danilvalov/2044c22be3c64ab0ce17d4bc853bae64 to your computer and use it in GitHub Desktop.
Rclone Deobscure function (Typescript/Javascript)
/*
This is a function to decrypt (deobscure) rclone passwords
Author: Danil Valov
Original code: https://github.com/maaaaz/rclonedeobscure (Thomas D.)
*/
import crypto from 'crypto';
// AES-256-CBC always has a block size of 16 bytes
const AESBlockSize = 16;
// -- https://github.com/rclone/rclone/blob/master/fs/config/obscure/obscure.go
const secretKey = Buffer.from([
0x9c, 0x93, 0x5b, 0x48, 0x73, 0x0a, 0x55, 0x4d, 0x6b, 0xfd, 0x7c, 0x63, 0xc8, 0x86, 0xa9, 0x2b, 0xd3, 0x90, 0x19,
0x8e, 0xb8, 0x12, 0x8a, 0xfb, 0xf4, 0xde, 0x16, 0x2b, 0x8b, 0x95, 0xf6, 0x38,
]);
const base64Urlsafedecode = (string: string): Buffer => {
const padding = 4 - (string.length % 4);
return Buffer.from(string + '='.repeat(padding), 'base64');
};
const aesCtrEncrypt = (encryptedPassword: Buffer, iv: Buffer) => {
const cipher = crypto.createDecipheriv('aes-256-ctr', secretKey, iv);
return cipher.update(encryptedPassword, undefined, 'utf-8') + cipher.final('utf-8');
};
export default (obscured: string): string => {
const encryptedPassword = base64Urlsafedecode(obscured);
const buf = encryptedPassword.slice(AESBlockSize);
const iv = encryptedPassword.slice(0, AESBlockSize);
return aesCtrEncrypt(buf, iv);
};
import rcloneDeobscure from './rclonedeobscure.ts';
const obscuredString = '9NUHOyrjZZimLXZbNvOegwkdv9d1XQAwCsrKXxsl';
const deobscuredString = rcloneDeobscure(obscuredString);
console.log(deobscuredString); // "secretpassword"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment