|
1 | 1 | using System.IO; |
2 | 2 | using System.IO.Compression; |
| 3 | +using System.Security.Cryptography; |
3 | 4 | using System.Text; |
4 | 5 | using ICSharpCode.SharpZipLib.Zip.Compression.Streams; |
5 | 6 |
|
6 | 7 | namespace GeometryDashAPI |
7 | 8 | { |
8 | 9 | public class Crypt |
9 | 10 | { |
| 11 | + // The MacOS save file is not encoded like the Windows one - instead, it uses AES ECB encryption. |
| 12 | + // Huge thanks to: https://github.com/qimiko/gd-save-tools/blob/b5176eb2c805ca65da3e51701409b72b90bdd497/assets/js/savefile.mjs#L43 |
| 13 | + private static byte[] MAC_SAVE_KEY = |
| 14 | + [ |
| 15 | + 0x69, 0x70, 0x75, 0x39, 0x54, 0x55, 0x76, 0x35, |
| 16 | + 0x34, 0x79, 0x76, 0x5D, 0x69, 0x73, 0x46, 0x4D, |
| 17 | + 0x68, 0x35, 0x40, 0x3B, 0x74, 0x2E, 0x35, 0x77, |
| 18 | + 0x33, 0x34, 0x45, 0x32, 0x52, 0x79, 0x40, 0x7B |
| 19 | + ]; |
| 20 | + |
10 | 21 | public static byte[] XOR(byte[] data, int key) |
11 | 22 | { |
12 | 23 | var result = new byte[data.Length]; |
@@ -53,5 +64,50 @@ public static byte[] GZipCompress(byte[] data) |
53 | 64 | } |
54 | 65 | return memory.ToArray(); |
55 | 66 | } |
| 67 | + |
| 68 | + public static byte[] SavingSaveAsMacOS(byte[] data) |
| 69 | + { |
| 70 | + using (Aes aesAlg = Aes.Create()) |
| 71 | + { |
| 72 | + aesAlg.Key = MAC_SAVE_KEY; |
| 73 | + aesAlg.Mode = CipherMode.ECB; |
| 74 | + |
| 75 | + ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); |
| 76 | + |
| 77 | + using (MemoryStream msEncrypt = new MemoryStream()) |
| 78 | + { |
| 79 | + using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) |
| 80 | + { |
| 81 | + csEncrypt.Write(data, 0, data.Length); |
| 82 | + } |
| 83 | + return msEncrypt.ToArray(); |
| 84 | + } |
| 85 | + } |
| 86 | + } |
| 87 | + |
| 88 | + public static string LoadSaveAsMacOS(byte[] data) |
| 89 | + { |
| 90 | + using (Aes aesAlg = Aes.Create()) |
| 91 | + { |
| 92 | + aesAlg.Key = MAC_SAVE_KEY; |
| 93 | + aesAlg.Mode = CipherMode.ECB; |
| 94 | + |
| 95 | + // Create a decryptor to perform the stream transform. |
| 96 | + ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); |
| 97 | + |
| 98 | + // Create the streams used for decryption. |
| 99 | + using (MemoryStream msDecrypt = new MemoryStream(data)) |
| 100 | + { |
| 101 | + using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) |
| 102 | + { |
| 103 | + using (StreamReader srDecrypt = new StreamReader(csDecrypt)) |
| 104 | + { |
| 105 | + // Read the decrypted bytes from the decrypting stream and place them in a string. |
| 106 | + return srDecrypt.ReadToEnd(); |
| 107 | + } |
| 108 | + } |
| 109 | + } |
| 110 | + } |
| 111 | + } |
56 | 112 | } |
57 | 113 | } |
0 commit comments