RPGM None [Translation Request] Xianxinglu of the Scarlet Moon, 绯月仙行录 V0.4164 [蓝月虫1988]

Nov 6, 2018
490
346
The bing translation is so bad i can't play it like that. Its been 3 years and not one translator took the job. Should we pitch it to kagura it might traslate it?
 

blackhedgehog

Active Member
Jul 3, 2018
529
275
The bing translation is so bad i can't play it like that. Its been 3 years and not one translator took the job. Should we pitch it to kagura it might traslate it?
According to the creator himself, he made an English version that is on his Patreon, I believe he will release an English version after the game comes out on Steam this year.
 

GodOfAll

Member
Aug 20, 2017
127
236
Btw, in case anyone wants to crack it, here is the code for decrypting all data files:


Python:
import os
import base64
import hashlib
from Crypto.Cipher import AES

def evp_bytes_to_key(password, salt, key_len, iv_len):
    """
    Derives the key and IV using OpenSSL's EVP_BytesToKey algorithm (MD5).
    """
    dtot = b""
    prev = b""
    while len(dtot) < key_len + iv_len:
        prev = hashlib.md5(prev + password + salt).digest()
        dtot += prev
    key = dtot[:key_len]
    iv = dtot[key_len:key_len+iv_len]
    return key, iv

def decrypt_file(encrypted_data, password):
    """
    Decrypts data encrypted by CryptoJS.AES.encrypt with a salted header.
    Expects a base64 string starting with "U2FsdGVkX1" (the encoded "Salted__" header).
    """
    encrypted_bytes = base64.b64decode(encrypted_data)
    if encrypted_bytes[:8] != b"Salted__":
        raise ValueError("Invalid data or missing salt header")
    salt = encrypted_bytes[8:16]
    ciphertext = encrypted_bytes[16:]
    key_len = 32  # 256-bit key
    iv_len = 16   # 128-bit IV
    key, iv = evp_bytes_to_key(password.encode("utf-8"), salt, key_len, iv_len)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = cipher.decrypt(ciphertext)
    # Remove PKCS7 padding
    pad_len = decrypted[-1]
    if pad_len < 1 or pad_len > 16:
        raise ValueError("Invalid padding encountered")
    return decrypted[:-pad_len]

def process_files_decrypt(source_dir, dest_dir, password):
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)
   
    for filename in os.listdir(source_dir):
        file_path = os.path.join(source_dir, filename)
        if os.path.isfile(file_path):
            print(f"Processing file: {filename}")
            with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
                content = f.read()
            # Check if file is encrypted (starts with base64 "Salted__")
            if content.startswith("U2FsdGVkX1"):
                try:
                    decrypted_bytes = decrypt_file(content, password)
                    decrypted_text = decrypted_bytes.decode("utf-8")
                    dest_path = os.path.join(dest_dir, filename)
                    with open(dest_path, "w", encoding="utf-8") as out_f:
                        out_f.write(decrypted_text)
                    print(f"Decrypted and saved: {dest_path}")
                except Exception as e:
                    print(f"Failed to decrypt {filename}: {str(e)}")
            else:
                print(f"File {filename} does not appear to be encrypted; copying as is.")
                dest_path = os.path.join(dest_dir, filename)
                with open(dest_path, "w", encoding="utf-8") as out_f:
                    out_f.write(content)

def main():
    # Change these values or enter paths when prompted.
    source_dir = input("Enter the path for the folder containing encrypted files: ").strip()
    dest_dir = input("Enter the path for the folder to save decrypted files: ").strip()
    password = "pojiecaonima"  # Encryption passphrase

    print("Starting decryption process...")
    process_files_decrypt(source_dir, dest_dir, password)
    print("Decryption process complete.")

if __name__ == "__main__":
    main()
then you have here the same for encrypting the translated files again:


Python:
import os
import base64
import hashlib
from Crypto.Cipher import AES

def evp_bytes_to_key(password, salt, key_len, iv_len):
    """
    Derives the key and IV using OpenSSL's EVP_BytesToKey algorithm (MD5).
    """
    dtot = b""
    prev = b""
    while len(dtot) < key_len + iv_len:
        prev = hashlib.md5(prev + password + salt).digest()
        dtot += prev
    key = dtot[:key_len]
    iv = dtot[key_len:key_len+iv_len]
    return key, iv

def encrypt_file(plaintext, password):
    """
    Encrypts plaintext using AES in CBC mode.
    Returns a base64-encoded string with the format:
    base64("Salted__" + salt (8 bytes) + ciphertext)
    Compatible with CryptoJS decryption.
    """
    plaintext_bytes = plaintext.encode("utf-8")
    salt = os.urandom(8)  # Generate a random 8-byte salt
    key_len = 32  # 256-bit key
    iv_len = 16   # 128-bit IV
    key, iv = evp_bytes_to_key(password.encode("utf-8"), salt, key_len, iv_len)
   
    # Apply PKCS7 padding
    pad_len = 16 - (len(plaintext_bytes) % 16)
    padding = bytes([pad_len]) * pad_len
    padded_text = plaintext_bytes + padding

    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted_bytes = cipher.encrypt(padded_text)
   
    # Prepend "Salted__" header and the salt, then base64 encode
    output_bytes = b"Salted__" + salt + encrypted_bytes
    return base64.b64encode(output_bytes).decode("utf-8")

def process_files_encrypt(source_dir, dest_dir, password):
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)
   
    for filename in os.listdir(source_dir):
        file_path = os.path.join(source_dir, filename)
        if os.path.isfile(file_path):
            print(f"Processing file: {filename}")
            with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
                content = f.read()
            try:
                encrypted_text = encrypt_file(content, password)
                dest_path = os.path.join(dest_dir, filename)
                with open(dest_path, "w", encoding="utf-8") as out_f:
                    out_f.write(encrypted_text)
                print(f"Encrypted and saved: {dest_path}")
            except Exception as e:
                print(f"Failed to encrypt {filename}: {str(e)}")

def main():
    # Change these values or enter paths when prompted.
    source_dir = input("Enter the path for the folder containing decrypted files: ").strip()
    dest_dir = input("Enter the path for the folder to save encrypted files: ").strip()
    password = "pojiecaonima"  # Encryption passphrase

    print("Starting encryption process...")
    process_files_encrypt(source_dir, dest_dir, password)
    print("Encryption process complete.")

if __name__ == "__main__":
    main()
So all together you just need to declare the input and output.
With this you can decrypt the files yourself
 

Kraiten

New Member
Jan 27, 2019
8
1
Btw, in case anyone wants to crack it, here is the code for decrypting all data files:


Python:
import os
import base64
import hashlib
from Crypto.Cipher import AES

def evp_bytes_to_key(password, salt, key_len, iv_len):
    """
    Derives the key and IV using OpenSSL's EVP_BytesToKey algorithm (MD5).
    """
    dtot = b""
    prev = b""
    while len(dtot) < key_len + iv_len:
        prev = hashlib.md5(prev + password + salt).digest()
        dtot += prev
    key = dtot[:key_len]
    iv = dtot[key_len:key_len+iv_len]
    return key, iv

def decrypt_file(encrypted_data, password):
    """
    Decrypts data encrypted by CryptoJS.AES.encrypt with a salted header.
    Expects a base64 string starting with "U2FsdGVkX1" (the encoded "Salted__" header).
    """
    encrypted_bytes = base64.b64decode(encrypted_data)
    if encrypted_bytes[:8] != b"Salted__":
        raise ValueError("Invalid data or missing salt header")
    salt = encrypted_bytes[8:16]
    ciphertext = encrypted_bytes[16:]
    key_len = 32  # 256-bit key
    iv_len = 16   # 128-bit IV
    key, iv = evp_bytes_to_key(password.encode("utf-8"), salt, key_len, iv_len)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = cipher.decrypt(ciphertext)
    # Remove PKCS7 padding
    pad_len = decrypted[-1]
    if pad_len < 1 or pad_len > 16:
        raise ValueError("Invalid padding encountered")
    return decrypted[:-pad_len]

def process_files_decrypt(source_dir, dest_dir, password):
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)
  
    for filename in os.listdir(source_dir):
        file_path = os.path.join(source_dir, filename)
        if os.path.isfile(file_path):
            print(f"Processing file: {filename}")
            with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
                content = f.read()
            # Check if file is encrypted (starts with base64 "Salted__")
            if content.startswith("U2FsdGVkX1"):
                try:
                    decrypted_bytes = decrypt_file(content, password)
                    decrypted_text = decrypted_bytes.decode("utf-8")
                    dest_path = os.path.join(dest_dir, filename)
                    with open(dest_path, "w", encoding="utf-8") as out_f:
                        out_f.write(decrypted_text)
                    print(f"Decrypted and saved: {dest_path}")
                except Exception as e:
                    print(f"Failed to decrypt {filename}: {str(e)}")
            else:
                print(f"File {filename} does not appear to be encrypted; copying as is.")
                dest_path = os.path.join(dest_dir, filename)
                with open(dest_path, "w", encoding="utf-8") as out_f:
                    out_f.write(content)

def main():
    # Change these values or enter paths when prompted.
    source_dir = input("Enter the path for the folder containing encrypted files: ").strip()
    dest_dir = input("Enter the path for the folder to save decrypted files: ").strip()
    password = "pojiecaonima"  # Encryption passphrase

    print("Starting decryption process...")
    process_files_decrypt(source_dir, dest_dir, password)
    print("Decryption process complete.")

if __name__ == "__main__":
    main()
then you have here the same for encrypting the translated files again:


Python:
import os
import base64
import hashlib
from Crypto.Cipher import AES

def evp_bytes_to_key(password, salt, key_len, iv_len):
    """
    Derives the key and IV using OpenSSL's EVP_BytesToKey algorithm (MD5).
    """
    dtot = b""
    prev = b""
    while len(dtot) < key_len + iv_len:
        prev = hashlib.md5(prev + password + salt).digest()
        dtot += prev
    key = dtot[:key_len]
    iv = dtot[key_len:key_len+iv_len]
    return key, iv

def encrypt_file(plaintext, password):
    """
    Encrypts plaintext using AES in CBC mode.
    Returns a base64-encoded string with the format:
    base64("Salted__" + salt (8 bytes) + ciphertext)
    Compatible with CryptoJS decryption.
    """
    plaintext_bytes = plaintext.encode("utf-8")
    salt = os.urandom(8)  # Generate a random 8-byte salt
    key_len = 32  # 256-bit key
    iv_len = 16   # 128-bit IV
    key, iv = evp_bytes_to_key(password.encode("utf-8"), salt, key_len, iv_len)
  
    # Apply PKCS7 padding
    pad_len = 16 - (len(plaintext_bytes) % 16)
    padding = bytes([pad_len]) * pad_len
    padded_text = plaintext_bytes + padding

    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted_bytes = cipher.encrypt(padded_text)
  
    # Prepend "Salted__" header and the salt, then base64 encode
    output_bytes = b"Salted__" + salt + encrypted_bytes
    return base64.b64encode(output_bytes).decode("utf-8")

def process_files_encrypt(source_dir, dest_dir, password):
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)
  
    for filename in os.listdir(source_dir):
        file_path = os.path.join(source_dir, filename)
        if os.path.isfile(file_path):
            print(f"Processing file: {filename}")
            with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
                content = f.read()
            try:
                encrypted_text = encrypt_file(content, password)
                dest_path = os.path.join(dest_dir, filename)
                with open(dest_path, "w", encoding="utf-8") as out_f:
                    out_f.write(encrypted_text)
                print(f"Encrypted and saved: {dest_path}")
            except Exception as e:
                print(f"Failed to encrypt {filename}: {str(e)}")

def main():
    # Change these values or enter paths when prompted.
    source_dir = input("Enter the path for the folder containing decrypted files: ").strip()
    dest_dir = input("Enter the path for the folder to save encrypted files: ").strip()
    password = "pojiecaonima"  # Encryption passphrase

    print("Starting encryption process...")
    process_files_encrypt(source_dir, dest_dir, password)
    print("Encryption process complete.")

if __name__ == "__main__":
    main()
So all together you just need to declare the input and output.
With this you can decrypt the files yourself
might be a dumb question, but how can I use it, I am not very familiar with Python, I can see your instruction to insert directory path, etc... but how can I run the code? Thank you in advance.
 

GodOfAll

Member
Aug 20, 2017
127
236
might be a dumb question, but how can I use it, I am not very familiar with Python, I can see your instruction to insert directory path, etc... but how can I run the code? Thank you in advance.
You can either download visual code, or you can fire it up over the cmd. Jus direct it where the py file with the code is. Hard to explain, yt videos are better for understanding.
 
  • Like
Reactions: Kraiten

dreminh

Active Member
Jan 4, 2019
559
295
Btw, in case anyone wants to crack it, here is the code for decrypting all data files:


Python:
import os
import base64
import hashlib
from Crypto.Cipher import AES

def evp_bytes_to_key(password, salt, key_len, iv_len):
    """
    Derives the key and IV using OpenSSL's EVP_BytesToKey algorithm (MD5).
    """
    dtot = b""
    prev = b""
    while len(dtot) < key_len + iv_len:
        prev = hashlib.md5(prev + password + salt).digest()
        dtot += prev
    key = dtot[:key_len]
    iv = dtot[key_len:key_len+iv_len]
    return key, iv

def decrypt_file(encrypted_data, password):
    """
    Decrypts data encrypted by CryptoJS.AES.encrypt with a salted header.
    Expects a base64 string starting with "U2FsdGVkX1" (the encoded "Salted__" header).
    """
    encrypted_bytes = base64.b64decode(encrypted_data)
    if encrypted_bytes[:8] != b"Salted__":
        raise ValueError("Invalid data or missing salt header")
    salt = encrypted_bytes[8:16]
    ciphertext = encrypted_bytes[16:]
    key_len = 32  # 256-bit key
    iv_len = 16   # 128-bit IV
    key, iv = evp_bytes_to_key(password.encode("utf-8"), salt, key_len, iv_len)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = cipher.decrypt(ciphertext)
    # Remove PKCS7 padding
    pad_len = decrypted[-1]
    if pad_len < 1 or pad_len > 16:
        raise ValueError("Invalid padding encountered")
    return decrypted[:-pad_len]

def process_files_decrypt(source_dir, dest_dir, password):
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)
  
    for filename in os.listdir(source_dir):
        file_path = os.path.join(source_dir, filename)
        if os.path.isfile(file_path):
            print(f"Processing file: {filename}")
            with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
                content = f.read()
            # Check if file is encrypted (starts with base64 "Salted__")
            if content.startswith("U2FsdGVkX1"):
                try:
                    decrypted_bytes = decrypt_file(content, password)
                    decrypted_text = decrypted_bytes.decode("utf-8")
                    dest_path = os.path.join(dest_dir, filename)
                    with open(dest_path, "w", encoding="utf-8") as out_f:
                        out_f.write(decrypted_text)
                    print(f"Decrypted and saved: {dest_path}")
                except Exception as e:
                    print(f"Failed to decrypt {filename}: {str(e)}")
            else:
                print(f"File {filename} does not appear to be encrypted; copying as is.")
                dest_path = os.path.join(dest_dir, filename)
                with open(dest_path, "w", encoding="utf-8") as out_f:
                    out_f.write(content)

def main():
    # Change these values or enter paths when prompted.
    source_dir = input("Enter the path for the folder containing encrypted files: ").strip()
    dest_dir = input("Enter the path for the folder to save decrypted files: ").strip()
    password = "pojiecaonima"  # Encryption passphrase

    print("Starting decryption process...")
    process_files_decrypt(source_dir, dest_dir, password)
    print("Decryption process complete.")

if __name__ == "__main__":
    main()
then you have here the same for encrypting the translated files again:


Python:
import os
import base64
import hashlib
from Crypto.Cipher import AES

def evp_bytes_to_key(password, salt, key_len, iv_len):
    """
    Derives the key and IV using OpenSSL's EVP_BytesToKey algorithm (MD5).
    """
    dtot = b""
    prev = b""
    while len(dtot) < key_len + iv_len:
        prev = hashlib.md5(prev + password + salt).digest()
        dtot += prev
    key = dtot[:key_len]
    iv = dtot[key_len:key_len+iv_len]
    return key, iv

def encrypt_file(plaintext, password):
    """
    Encrypts plaintext using AES in CBC mode.
    Returns a base64-encoded string with the format:
    base64("Salted__" + salt (8 bytes) + ciphertext)
    Compatible with CryptoJS decryption.
    """
    plaintext_bytes = plaintext.encode("utf-8")
    salt = os.urandom(8)  # Generate a random 8-byte salt
    key_len = 32  # 256-bit key
    iv_len = 16   # 128-bit IV
    key, iv = evp_bytes_to_key(password.encode("utf-8"), salt, key_len, iv_len)
  
    # Apply PKCS7 padding
    pad_len = 16 - (len(plaintext_bytes) % 16)
    padding = bytes([pad_len]) * pad_len
    padded_text = plaintext_bytes + padding

    cipher = AES.new(key, AES.MODE_CBC, iv)
    encrypted_bytes = cipher.encrypt(padded_text)
  
    # Prepend "Salted__" header and the salt, then base64 encode
    output_bytes = b"Salted__" + salt + encrypted_bytes
    return base64.b64encode(output_bytes).decode("utf-8")

def process_files_encrypt(source_dir, dest_dir, password):
    if not os.path.exists(dest_dir):
        os.makedirs(dest_dir)
  
    for filename in os.listdir(source_dir):
        file_path = os.path.join(source_dir, filename)
        if os.path.isfile(file_path):
            print(f"Processing file: {filename}")
            with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
                content = f.read()
            try:
                encrypted_text = encrypt_file(content, password)
                dest_path = os.path.join(dest_dir, filename)
                with open(dest_path, "w", encoding="utf-8") as out_f:
                    out_f.write(encrypted_text)
                print(f"Encrypted and saved: {dest_path}")
            except Exception as e:
                print(f"Failed to encrypt {filename}: {str(e)}")

def main():
    # Change these values or enter paths when prompted.
    source_dir = input("Enter the path for the folder containing decrypted files: ").strip()
    dest_dir = input("Enter the path for the folder to save encrypted files: ").strip()
    password = "pojiecaonima"  # Encryption passphrase

    print("Starting encryption process...")
    process_files_encrypt(source_dir, dest_dir, password)
    print("Encryption process complete.")

if __name__ == "__main__":
    main()
So all together you just need to declare the input and output.
With this you can decrypt the files yourself
am bad in english can you sent me a link so i can follow Instructions