Ошибка "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 шт):
Код GPT писал? Почему такой странный?
А почему у вас ключ 16 байт, когда должен быть 32 по умолчанию? Собственно, это и есть причина всех проблем, проверьте Aes.KeySize
, оно вернёт вам длину ключа в битах, делим на 8, получаем байты.
Обратите внимание, вы ни ключ ни IV не используете в методе Encrypt
. Это тоже ошибка.
К тому же IV нет смысла хардкодить, пусть он будет рандомным и писать его прямо в данные.
Вот примеры:
Хардкодить ключ в скрипт нельзя, это позволит его легко добыть. Подумайте, куда его деть. Про IV я уже сказал, он не секретный и его не надо выдумывать, пусть будет случайным. Пишите IV в данные, оттуда же читайте перед расшифровкой.