public static byte[] DecryptBCAT(byte[] data, ulong TitleID, string passStr) { byte[] dec; using (MemoryStream ms = new MemoryStream(data)) { BinaryReader br = new BinaryReader(ms); //read the magic string magic = Encoding.ASCII.GetString(br.ReadBytes(4)); if (magic != BCAT_MAGIC) { throw new Exception("Invalid bcat header!"); } br.BaseStream.Position++; //unknow byte crypto = br.ReadByte(); byte rsaType = br.ReadByte(); byte secretIndex = br.ReadByte(); br.BaseStream.Position += 8; //padding byte[] iv = br.ReadBytes(0x10); byte[] rsa = br.ReadBytes(0x100); byte[] enc = br.ReadBytes((int)(br.BaseStream.Length - 0x120)); if (crypto > 3) { return(enc); } int kSize = (crypto + 1) * 8; byte[] salt = Encoding.ASCII.GetBytes(TitleID.ToString("x16") + Program.Config.SaltLower[secretIndex]); byte[] pass = Encoding.ASCII.GetBytes(passStr); byte[] key = PBKDF2Sha256GetBytes(kSize, pass, salt, 4096); dec = AesCrypto.PerformAesCTR(enc, 0, enc.Length, key, iv); } return(dec); }
public static byte[] EncryptBCAT(byte[] data, ulong TitleID, string passStr, byte HashType, byte crypto, byte[] signature) { byte[] output; using (MemoryStream ms = new MemoryStream()) { BinaryWriter bw = new BinaryWriter(ms); Random rnd = new Random(); byte[] iv = new byte[0x10]; rnd.NextBytes(iv); //generate random iv int secretIndex = rnd.Next(0, 31); //generate random secret index bw.Write(Encoding.ASCII.GetBytes(BCAT_MAGIC)); bw.Write((byte)1); //must be 1 for some reasons bw.Write(crypto); bw.Write(HashType); bw.Write((byte)secretIndex); bw.Write(new byte[8]); //padding bw.Write(iv); bw.Write(signature); if (crypto > 3) { bw.Write(data); } else { int kSize = (crypto + 1) * 8; byte[] salt = Encoding.ASCII.GetBytes(TitleID.ToString("x16") + Program.Config.SaltLower[secretIndex]); byte[] pass = Encoding.ASCII.GetBytes(passStr); byte[] key = PBKDF2Sha256GetBytes(kSize, pass, salt, 4096); bw.Write(AesCrypto.PerformAesCTR(data, 0, data.Length, key, iv)); } output = ms.ToArray(); } return(output); }