private static byte[] EncryptPekList(byte[] cleartextBlob, PekListVersion pekListVersion, byte[] bootKey = null) { // Do not encrypt by default. PekListFlags flags = PekListFlags.Clear; if (bootKey != null) { // Encrypt if the boot key is provided. Validator.AssertLength(bootKey, BootKeyRetriever.BootKeyLength, "bootKey"); flags = PekListFlags.Encrypted; } // Generate random salt byte[] salt = GenerateSalt(SaltSize); // Encode the data structure using (MemoryStream stream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(stream)) { // Header writer.Write((uint)pekListVersion); writer.Write((uint)flags); writer.Write(salt); // Data switch (flags) { case PekListFlags.Clear: writer.Write(cleartextBlob); break; case PekListFlags.Encrypted: byte[] encryptedBlob; switch (pekListVersion) { case PekListVersion.W2016: encryptedBlob = EncryptUsingAES(cleartextBlob, salt, bootKey); writer.Write(encryptedBlob); // Add 16B zeroed padding. The purpose in unknown and NTDS even works without it. byte[] padding = new byte[PekListV3PaddingSize]; writer.Write(padding); break; case PekListVersion.W2k: encryptedBlob = EncryptUsingRC4(cleartextBlob, salt, bootKey, BootKeySaltHashRounds); writer.Write(encryptedBlob); break; default: // TODO: Extract as a resource. throw new FormatException("Unsupported PEK list version."); } break; } } return(stream.ToArray()); } }
private static byte[] EncryptPekList(byte[] cleartextBlob, PekListVersion pekListVersion, byte[] bootKey = null) { // Do not encrypt by default. PekListFlags flags = PekListFlags.Clear; if (bootKey != null) { // Encrypt if the boot key is provided. Validator.AssertLength(bootKey, BootKeyRetriever.BootKeyLength, "bootKey"); flags = PekListFlags.Encrypted; } // Generate random salt byte[] salt = new byte[SaltSize]; using (var rng = RandomNumberGenerator.Create()) { rng.GetBytes(salt); } // Encode the data structure using (MemoryStream stream = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(stream)) { // Header writer.Write((uint)pekListVersion); writer.Write((uint)flags); writer.Write(salt); // Data switch (flags) { case PekListFlags.Clear: writer.Write(cleartextBlob); break; case PekListFlags.Encrypted: byte[] encryptedBlob; switch (pekListVersion) { case PekListVersion.W2016: encryptedBlob = EncryptUsingAES(cleartextBlob, salt, bootKey, PaddingMode.Zeros); break; case PekListVersion.W2k: encryptedBlob = EncryptUsingRC4(cleartextBlob, salt, bootKey, BootKeySaltHashRounds); break; default: // TODO: Extract as a resource. throw new FormatException("Unsupported PEK list version."); } writer.Write(encryptedBlob); break; } } return(stream.ToArray()); } }
public DataStoreSecretDecryptor(byte[] cleartextPEKListBlob, PekListVersion version) { this.Version = version; this.ParsePekList(cleartextPEKListBlob); }