跳转至

rclone配置文件加解密

因开发AutoUploader需要研究rclone.conf是如何加密配置文件的,经过多次尝试,终于找到相关的代码实现:

加密配置

加密代码:

Python
import base64
import hashlib
import os
import shutil

from nacl.secret import SecretBox


def new_config_key(password):
    password_str = '[%s][rclone-config]' % password
    m = hashlib.sha256()
    m.update(password_str.encode())
    result = m.digest()
    return result


# Example usage:
password = "123321"
config_key = new_config_key(password)


def encrypt_config(src, dst):
    if len(config_key) == 0:
        shutil.copyfileobj(src, dst)
        return

    dst.write(b"# Encrypted rclone configuration File\n\n")
    dst.write(b"RCLONE_ENCRYPT_V0:\n")

    # Generate new nonce and write it to the start of the ciphertext
    nonce = os.urandom(24)
    enc = base64.b64encode(nonce).decode('utf-8') + '\n'
    # dst.write(enc.encode('utf-8'))

    key = config_key[:32]

    data = src.read()
    box = SecretBox(key)
    ciphertext = box.encrypt(data, nonce)
    enc = base64.b64encode(ciphertext).decode('utf-8') + '\n'
    dst.write(enc.encode('utf-8'))


# Example usage:
with open('rclone123.conf', 'rb') as src, open('rclone.conf', 'wb') as dst:
    encrypt_config(src, dst)

加密原理

rclone加密配置文件的原理是通过Nacl+SHA-256算法进行加密,头部需要插入一段24个字节的随机值,密码部分采用sha-256加密并去前32个字节作为密钥,然后待加密文本数据(二进制)放入Secret中进行加密,之后再将混淆值+加密后的数据进行base64编码以二进制写入到文本中 解密原理同理,只是反着来

解密配置

解密代码实现:

Python
import base64  
import hashlib  

from nacl.secret import SecretBox  


def new_config_key(password):  
    password_str = '[%s][rclone-config]' % password    
    m = hashlib.sha256()    
    m.update(password_str.encode())    
    result = m.digest()    
    return result  

password = "123321"  
config_key = new_config_key(password)  
print(f"Config Key: {config_key}")  
# new_config_key(password)  
print('-' * 50)  

src_text = """1sQiSyHr8k3IcLVH+UKd82YQM9cOpkM"""  
b64_data = base64.b64decode(src_text)  
nonce = b64_data[:24]  
encrypted_data = b64_data[24:]  

box = SecretBox(config_key[:32])  
decrypted_data = box.decrypt(encrypted_data, nonce)  

with open('test.ini', 'wb') as f:  
    f.write(decrypted_data)