public byte[] HandleRequest(byte[] kmsRequestData) { KMSV5Request kmsv5Request = CreateKMSV5Request(kmsRequestData); byte[] decrypted = DecryptV5(kmsv5Request); byte[] decryptedSalt = decrypted.Take(16).ToArray(); byte[] decryptedRequest = decrypted.Skip(16).ToArray(); byte[] responseBytes = Server.ExecuteKMSServerLogic(decryptedRequest, Logger); byte[] randomSalt = Guid.NewGuid().ToByteArray(); byte[] randomSaltHash = GetSHA265Hash(randomSalt); byte[] randomStuff = new byte[16]; for (int i = 0; i < 16; i++) { randomStuff[i] = (byte)(decryptedSalt[i] ^ kmsv5Request.Salt[i] ^ randomSalt[i]); } byte[] responsedata = responseBytes.Concat(randomStuff).Concat(randomSaltHash).ToArray(); byte[] encryptedResponseData = EncryptV5(responsedata, kmsv5Request.Salt); KMSV5Response kmsResponse = new KMSV5Response { Version = kmsv5Request.Version, Salt = kmsv5Request.Salt, Encrypted = encryptedResponseData }; byte[] encryptedResponse = CreateKMSV5ResponseBytes(kmsResponse); return(encryptedResponse); }
private static KMSV5Request CreateKMSV5Request(byte[] kmsRequestData) { KMSV5Request kmsRequest = new KMSV5Request(); using (MemoryStream stream = new MemoryStream(kmsRequestData)) { using BinaryReader binaryReader = new BinaryReader(stream); kmsRequest.BodyLength1 = binaryReader.ReadUInt32(); kmsRequest.BodyLength2 = binaryReader.ReadUInt32(); kmsRequest.Version = binaryReader.ReadUInt32(); kmsRequest.Salt = binaryReader.ReadBytes(16); kmsRequest.EncryptedRequest = binaryReader.ReadBytes(kmsRequestData.Length - 8 - 4 - 16 - 4); kmsRequest.Pad = binaryReader.ReadBytes(4); } return(kmsRequest); }
private static byte[] DecryptV5(KMSV5Request kmsRequest) { byte[] iv = kmsRequest.Salt; byte[] encrypted = kmsRequest.Salt.Concat(kmsRequest.EncryptedRequest) .Concat(kmsRequest.Pad).ToArray(); RijndaelManaged rijndaelManaged = new RijndaelManaged { Key = Key, IV = iv }; byte[] decrypted; using (MemoryStream ms = new MemoryStream()) { using (CryptoStream cs = new CryptoStream(ms, rijndaelManaged.CreateDecryptor(), CryptoStreamMode.Write)) { cs.Write(encrypted, 0, encrypted.Length); } decrypted = ms.ToArray(); } return(decrypted); }