A personal journal.

Mencari Kembali Password yang Terlupa pada Berkas Konfigurasi rclone.conf

Published on: 02/03/2023 • Updated on: 13/05/2025 • 1 min read

Rclone adalah perangkat lunak open-source yang memungkinkan kamu melakukan sinkronisasi dan backup data ke berbagai penyimpanan cloud. Tetapi terkadang kamu dapat kehilangan passwordmu, yang dapat menyebabkan masalah saat mencoba mengakses penyimpanan awan yang dihubungkan.

Saya sempat beberapa kali mengalami masalah ini, namun karena belum ada cara mengatasinya, saya hanya pasrah dengan semua file saya yang hilang dan tidak bisa diakses.

Tetapi beberapa tahun lalu (ya sebetulnya sudah lama, cuma baru ingat dan ingin saya tulis supaya tetap ingat), saya menemukan cara men decrypt password, berdasarkan pseudo-encrypted password yang kamu miliki di dalam file rclone.conf. Langsung saja, berikut adalah isi dari programnya:

package main

import (
    "crypto/aes"
    "crypto/cipher"
    "crypto/rand"
    "encoding/base64"
    "errors"
    "fmt"
    "log"
)

// crypt internals
var (
    cryptKey = []byte{
        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,
    }
    cryptBlock cipher.Block
    cryptRand  = rand.Reader
)

// crypt transforms in to out using iv under AES-CTR.
//
// in and out may be the same buffer.
//
// Note encryption and decryption are the same operation
func crypt(out, in, iv []byte) error {
    if cryptBlock == nil {
        var err error
        cryptBlock, err = aes.NewCipher(cryptKey)
        if err != nil {
            return err
        }
    }
    stream := cipher.NewCTR(cryptBlock, iv)
    stream.XORKeyStream(out, in)
    return nil
}

// Reveal an obscured value
func Reveal(x string) (string, error) {
    ciphertext, err := base64.RawURLEncoding.DecodeString(x)
    if err != nil {
        return "", fmt.Errorf("base64 decode failed when revealing password - is it obscured? %w", err)
    }
    if len(ciphertext) < aes.BlockSize {
        return "", errors.New("input too short when revealing password - is it obscured?")
    }
    buf := ciphertext[aes.BlockSize:]
    iv := ciphertext[:aes.BlockSize]
    if err := crypt(buf, buf, iv); err != nil {
        return "", fmt.Errorf("decrypt failed when revealing password - is it obscured? %w", err)
    }
    return string(buf), nil
}

// MustReveal reveals an obscured value, exiting with a fatal error if it failed
func MustReveal(x string) string {
    out, err := Reveal(x)
    if err != nil {
        log.Fatalf("Reveal failed: %v", err)
    }
    return out
}

func main() {
    fmt.Println(MustReveal("YOUR PSEUDO-ENCRYPTED PASSWORD HERE"))
}

Sayangnya saya lupa dari mana saya mendapatkan sumber ini, tetapi untuk script-nya saya bookmark dan simpan. Untuk script, bisa kamu lihat disini.

Semoga bermanfaat!