public static bool DecryptNisasyst(FileInfo input, string path, FileInfo output) { using (FileStream fileStream = input.OpenRead()) using (StreamReader streamReader = new StreamReader(fileStream)) { // Test the file length if (fileStream.Length <= 8) { // This can't be a valid file return(false); } // Seek to the magic numbers fileStream.Seek(-8, SeekOrigin.End); // Verify the magic numbers if (streamReader.ReadToEnd() != MagicNumbers) { // This isn't a valid file return(false); } // Generate a CRC32 over the game path Crc32 crc32 = new Crc32(); uint seed = crc32.Get(Encoding.ASCII.GetBytes(path)); // Create a new SeadRandom instance using the seed SeadRandom seadRandom = new SeadRandom(seed); // Create the encryption key and IV byte[] encryptionKey = CreateSequence(seadRandom); byte[] iv = CreateSequence(seadRandom); using (MemoryStream memoryStream = new MemoryStream()) using (AesManaged cryptor = new AesManaged()) { cryptor.Mode = CipherMode.CBC; cryptor.Padding = PaddingMode.PKCS7; cryptor.KeySize = 128; cryptor.BlockSize = 128; using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptor.CreateDecryptor(encryptionKey, iv), CryptoStreamMode.Write)) { // Seek to the beginning of the file fileStream.Seek(0, SeekOrigin.Begin); // Copy the encrypted data CopyStream(fileStream, cryptoStream, (int)fileStream.Length - 8); } // Write out the new file byte[] outputBytes = memoryStream.ToArray(); output.Directory.Create(); using (FileStream outputStream = output.Create()) outputStream.Write(outputBytes, 0, outputBytes.Length); return(true); } } }
private static byte[] CreateSequence(SeadRandom random) { // Create byte array byte[] sequence = new byte[16]; // Create each byte for (int i = 0; i < sequence.Length; i++) { // Create empty byte string string byteString = "";// "0x"; // Get characters from key material byteString += KeyMaterialString[(int)(random.GetUInt32() >> 24)]; byteString += KeyMaterialString[(int)(random.GetUInt32() >> 24)]; // Parse the resulting byte sequence[i] = Convert.ToByte(byteString, 16); } // Return the sequence return(sequence); }