Encrypting and decrypting audio clip to file unity

651 views Asked by At

I'm using AES for encrypting and decrypting, I can write it to a file and when I try to read the file back to audio clip, I'm getting input exception

I tried to convert the audio file to base64 byte array while saving in file so that when I read the file I can read it as byte array which is required for creating audio clip

I have attached the code below

 private float[] ConvertByteToFloat(byte[] array)
{
    float[] floatArr = new float[array.Length / 4];
    for (int i = 0; i < floatArr.Length; i++)
    {
        if (BitConverter.IsLittleEndian)
        {
            Array.Reverse(array, i * 4, 4);
        }
        floatArr[i] = BitConverter.ToSingle(array, i * 4) / 0x80000000;
    }
    return floatArr;
}

public void ReadFile()
{
    // Does the file exist AND does the "key" preference exist?
    if (File.Exists(saveFile) && PlayerPrefs.HasKey("Key"))
    {
        // Update key based on PlayerPrefs
        // (Convert the String into a Base64 byte[] array.)
        byte[] savedKey = Convert.FromBase64String(PlayerPrefs.GetString("Key"));
        byte[] savedIV = Convert.FromBase64String(PlayerPrefs.GetString("IV"));

        // Create FileStream for opening files.
        dataStream = new FileStream(saveFile, FileMode.Open);

        Debug.Log(PlayerPrefs.GetString("Key"));

        // Create new AES instance.
        Aes oAes = Aes.Create();

        // Create an array of correct size based on AES IV.
        byte[] outputIV = new byte[savedIV.Length];

        // Read the IV from the file.
        dataStream.Read(savedIV, 0, outputIV.Length);

        // Create CryptoStream, wrapping FileStream
        CryptoStream oStream = new CryptoStream(dataStream, oAes.CreateDecryptor(savedKey, outputIV), CryptoStreamMode.Read);

        // Create a StreamReader, wrapping CryptoStream
        StreamReader reader = new StreamReader(oStream);

        // Read the entire file into a String value.
        string text = reader.ReadToEnd();

        byte[] songDataBytes = Convert.FromBase64String(text);

        AudioClip audioClip = AudioClip.Create("SongName", songDataBytes.Length, 1, 48000, false);
        float[] f = ConvertByteToFloat(songDataBytes);
        audioClip.SetData(f, 0);
        ass.clip = audioClip;
        ass.Play();

        Debug.Log("C");
        // Deserialize the JSON data 
        //  into a pattern matching the GameData class.
        //gameData = JsonUtility.FromJson<GameData>(text);
    }
    Debug.Log("D");
}



public void WriteFile()
{
    string songLoc = Application.persistentDataPath + "/song.mp3";

    // Create new AES instance.
    Aes iAes = Aes.Create();

    // Update the internal key.
    string key = PlayerPrefs.GetString("Key");
    string IV = PlayerPrefs.GetString("Key");

    byte[] savedKey;
    byte[] savedIV;

    if (key == "")
    {
        iAes.GenerateIV();
        savedKey = iAes.Key;
        savedIV = iAes.IV;
        key = Convert.ToBase64String(savedKey);
        IV = Convert.ToBase64String(savedIV);
    }
    else
    {
        savedIV = Convert.FromBase64String(PlayerPrefs.GetString("IV"));
        savedKey = Convert.FromBase64String(PlayerPrefs.GetString("Key"));
    }

    Debug.Log(key);

    // Convert the byte[] into a Base64 String.
    //string key = System.Convert.ToBase64String(savedKey);

    // Update the PlayerPrefs
    PlayerPrefs.SetString("Key", key);
    PlayerPrefs.SetString("IV", IV);


    // Create a FileStream for creating files.
    dataStream = new FileStream(saveFile, FileMode.Create);

    // Save the new generated IV.
    byte[] inputIV = savedIV;

    // Write the IV to the FileStream unencrypted.
    dataStream.Write(inputIV, 0, inputIV.Length);

    // Create CryptoStream, wrapping FileStream.
    CryptoStream iStream = new CryptoStream(dataStream, iAes.CreateEncryptor(savedKey, savedIV), CryptoStreamMode.Write);

    // Create StreamWriter, wrapping CryptoStream.
    StreamWriter sWriter = new StreamWriter(iStream);

    // Serialize the object into JSON and save string.
    byte[] songData = File.ReadAllBytes(songLoc);

    //string songString = Convert.ToBase64String(songData);
    //File.WriteAllBytes(saveFile, songData);

    // Write to the innermost stream (which will encrypt).
    sWriter.BaseStream.Write(songData, 0, songData.Length);

    // Close StreamWriter.
    sWriter.Close();

    // Close CryptoStream.
    iStream.Close();

    // Close FileStream.
    dataStream.Close();
}
0

There are 0 answers