Ошибка "Bad PKCS7 padding. Invalid length" при расшифровке файла с помощью AES

Ошибка: Ошибка при расшифровке данных: Bad PKCS7 padding. Invalid length 0.

Простите, я все натыкал в один скрипт.

using System.Collections;
using TMPro;
using UnityEngine;
using UnityEngine.UIElements;
using Color = UnityEngine.Color;
using UnityEngine.Profiling;
using System;
using UnityEngine.UI;
using System.IO;
using System.Security.Cryptography;
using System.Text;


public class Player : MonoBehaviour
{
    public float speed_rotation;
    private Vector3 Rotation;

    private float Score;
    [SerializeField] public float Record;
    private bool Right = false;
    public Enemy _enemy;

    public LayerMask Enemy;    
    public Transform point;

    public Animator player_;
    public Animator menu;

    private Player script;

    public GameObject camera;
    private SpriteRenderer sr;

    public GameObject Menu;
    public TextMeshProUGUI score;
    public TextMeshProUGUI record;
    public Text recordText; // Reference to your record text UI element

    public byte[] key = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
    public byte[] iv = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };


    private void Awake()
    {
        script = GetComponent<Player>();
        sr = GetComponentInChildren<SpriteRenderer>();
    }
    void FixedUpdate()
    {
        //Moved
        

        Rotation = transform.rotation.eulerAngles;
        if (Right)
        {
            
            Rotation.z -= speed_rotation;
        }
        else if (!Right)
        {
            Rotation.z += speed_rotation;
        }
        transform.rotation = Quaternion.Euler(Rotation);
    }

    private void Update()
    {

        //Click

        if (Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);
            if (touch.phase == TouchPhase.Began && Bools())
            {
                speed_rotation *= 1.1f;
                Score += 5;
                
                if (Right)
                {
                    Right = false;
                }
                else
                {
                    Right = true;
                }
                _enemy.Destroy();
                StartCoroutine(Camera());
                
            }
            else if (touch.phase == TouchPhase.Began && !Bools())
            {
                player_.SetBool("Destroy", true);
                if (Score > Record)
                {
                    Record = Score;
                }
                SavePlayerData();
                score.text = "Score:" + Score;                
                record.text = "Record:" + Record;
                Menu.SetActive(true);
                menu.SetBool("Open", true);
                script.enabled = false;  
            }
        }
    }

    //Check bool

    private bool Bools()
    {
        return Physics2D.Raycast(point.position, transform.up, Enemy);
    }

    IEnumerator Camera()
    {
        for (int i = 0; i < 4; i++)
        {
            camera.transform.position = new Vector3(UnityEngine.Random.Range(-0.3f, 0.3f), UnityEngine.Random.Range(-0.3f, 0.3f), camera.transform.position.z);
            yield return new WaitForSeconds(0.025f);

            if (i == 3)
            {
                camera.transform.position = new Vector3(0, 0, camera.transform.position.z);
            }
        }

    }

    public void Restart()
    {
        transform.rotation = Quaternion.Euler(0, 0, 0);
        player_.SetBool("Destroy", false);
        sr.color = new Color(255, 255, 255, 255);
        Menu.SetActive(false);
        script.enabled = true;
        Score = 0;
        speed_rotation = 1;
        _enemy.Teleport();
    }









    // Сохранение данных
    private void OnApplicationQuit()
    {
        SavePlayerData();
    }

    private void SavePlayerData()
    {
        // Преобразовать данные в JSON
        string jsonData = JsonUtility.ToJson(new PlayerData(Record));

        // Зашифровать данные
        string encryptedData = Encrypt(jsonData, key, iv);

        // Добавить логи для отладки
        Debug.Log("Данные JSON: " + jsonData);
        Debug.Log("Зашифрованные данные: " + encryptedData);

        // Сохранить зашифрованные данные, ключ и IV
        PlayerPrefs.SetString("saveData", encryptedData);
        PlayerPrefs.SetString("key", Convert.ToBase64String(key));
        PlayerPrefs.SetString("iv", Convert.ToBase64String(iv));
    }

    void Start()
    {
        // Загрузка данных (если они существуют)
        LoadRecord();
    }

    void LoadRecord()
    {
        // Получить зашифрованные данные
        string encryptedData = PlayerPrefs.GetString("saveData");

        // Проверить наличие данных
        if (string.IsNullOrEmpty(encryptedData))
        {
            Debug.Log("Сохраненные данные не найдены.");
            return;
        }

        // Получить ключ и IV
        string keyString = PlayerPrefs.GetString("key");
        string ivString = PlayerPrefs.GetString("iv");

        // Преобразовать ключ и IV из Base64 в массив байт
        byte[] key = Convert.FromBase64String(keyString);
        byte[] iv = Convert.FromBase64String(ivString);

        try
        {
            // Расшифровать данные
            string jsonData = Decrypt(encryptedData, iv, key);

            // Добавить логи для отладки
            Debug.Log("Зашифрованные данные: " + encryptedData);
            Debug.Log("Расшифрованные данные: " + jsonData);

            // Преобразовать JSON в данные
            PlayerData data = JsonUtility.FromJson<PlayerData>(jsonData);

            // Обновить рекорд и UI
            Record = data.Record;
            recordText.text = "Рекорд: " + Record;
        }
        catch (Exception e)
        {
            Debug.LogError("Ошибка при расшифровке данных: " + e.Message);
            // Обработать ошибку, например, удалить поврежденные данные
        }
    }

    public struct PlayerData
    {
        public float Record;

        public PlayerData(float record)
        {
            Record = record;
        }
    }

    public static string Encrypt(string data, byte[] key, byte[] iv)
    {
        // Преобразовать строку в массив байт
        byte[] dataBytes = Encoding.UTF8.GetBytes(data);

        // Создать объект AES с ключом и IV
        using (Aes aes = Aes.Create())
        {
            // Создать шифратор
            ICryptoTransform encryptor = aes.CreateEncryptor();

            // Создать поток для шифрования данных
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                {
                    cs.Write(dataBytes, 0, dataBytes.Length);
                }

                // Вернуть зашифрованные данные в виде строки Base64
                return Convert.ToBase64String(ms.ToArray());
            }
        }
    }

    public static string Decrypt(string encryptedData, byte[] iv, byte[] key)
    {
        try
        {
            using (Aes aes = Aes.Create())
            {
                aes.Key = key;
                aes.IV = iv;

                ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

                byte[] encryptedBytes = Convert.FromBase64String(encryptedData);

                using (MemoryStream msDecrypt = new MemoryStream(encryptedBytes))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            return srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Debug.LogError("Ошибка при расшифровке данных: " + ex.Message);
            return null;
        }
    }
}

Пожалуйста, помогите. Уже два дня мучаюсь с этим.


Ответы (1 шт):

Автор решения: aepot

Код GPT писал? Почему такой странный?

А почему у вас ключ 16 байт, когда должен быть 32 по умолчанию? Собственно, это и есть причина всех проблем, проверьте Aes.KeySize, оно вернёт вам длину ключа в битах, делим на 8, получаем байты.

Обратите внимание, вы ни ключ ни IV не используете в методе Encrypt. Это тоже ошибка.

К тому же IV нет смысла хардкодить, пусть он будет рандомным и писать его прямо в данные.

Вот примеры:

Хардкодить ключ в скрипт нельзя, это позволит его легко добыть. Подумайте, куда его деть. Про IV я уже сказал, он не секретный и его не надо выдумывать, пусть будет случайным. Пишите IV в данные, оттуда же читайте перед расшифровкой.

→ Ссылка