Generate Kerberos AES keys from a known password The article describes a PowerShell function called `Get-KerberosAESKey` that generates Kerberos AES 128/256 encryption keys from a known password, salt (comprising the Kerberos realm and username/hostname), and iteration count. The function uses PBKDF2 to derive keys and has been verified against test values from RFC3962 and MS-KILE. It was authored by Kevin Robertson and is licensed under BSD 3-Clause. Get-KerberosAESKey.ps1 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters Show hidden characters function Get-KerberosAESKey { < .SYNOPSIS Generate Kerberos AES 128/256 keys from a known username/hostname, password, and kerberos realm. The results have been verified against the test values in RFC3962, MS-KILE, and my own test lab. https://tools.ietf.org/html/rfc3962 https://msdn.microsoft.com/library/cc233855.aspx Author: Kevin Robertson @kevin robertson License: BSD 3-Clause .PARAMETER Password String Valid password. .PARAMETER Salt String Concatenated string containing the realm and username/hostname. AD username format = uppercase realm + case sensitive username e.g., TEST.LOCALusername, TEST.LOCALAdministrator AD hostname format = uppercase realm + the word host + lowercase hostname without the trailing '$' + . + lowercase realm e.g., TEST.LOCALhostwks1.test.local .PARAMETER Iteration Integer Default = 4096: Int value representing how many iterations of PBKDF2 will be performed. AD uses the default of 4096. .PARAMETER OutputType String Default = AES: AES,AES128,AES256,AES128ByteArray,AES256ByteArray AES, AES128, and AES256 will output strings. AES128Byte and AES256Byte will output byte arrays. .EXAMPLE Verify results against first RFC3962 sample test vectors in section B. Get-KerberosAESKey -Password password -Salt ATHENA.MIT.EDUraeburn -Iteration 1 .EXAMPLE Generate keys for a valid AD user. Get-KerberosAESKey -Salt TEST.LOCALuser .LINK https://gist.github.com/kevin-robertson/ CmdletBinding param parameter Mandatory=$false String $Password, parameter Mandatory=$true String $Salt, parameter Mandatory=$false ValidateSet "AES","AES128","AES256","AES128ByteArray","AES256ByteArray" String $OutputType = "AES", parameter Mandatory=$false Int $Iteration=4096 if $Password { $secure password = Read-Host -Prompt "Enter password" -AsSecureString $password memory = System.Runtime.InteropServices.Marshal ::SecureStringToBSTR $secure password $password = System.Runtime.InteropServices.Marshal ::PtrToStringAuto $password memory } Byte $password bytes = System.Text.Encoding ::UTF8.GetBytes $Password Byte $salt bytes = System.Text.Encoding ::UTF8.GetBytes $Salt $AES256 constant = 0x6B,0x65,0x72,0x62,0x65,0x72,0x6F,0x73,0x7B,0x9B,0x5B,0x2B,0x93,0x13,0x2B,0x93,0x5C,0x9B,0xDC,0xDA,0xD9,0x5C,0x98,0x99,0xC4,0xCA,0xE4,0xDE,0xE6,0xD6,0xCA,0xE4 $AES128 constant = 0x6B,0x65,0x72,0x62,0x65,0x72,0x6F,0x73,0x7B,0x9B,0x5B,0x2B,0x93,0x13,0x2B,0x93 $IV = 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 $PBKDF2 = New-Object Security.Cryptography.Rfc2898DeriveBytes $password bytes,$salt bytes,$iteration $PBKDF2 AES256 key = $PBKDF2.GetBytes 32 $PBKDF2 AES128 key = $PBKDF2 AES256 key 0..15 $PBKDF2 AES256 key string = System.BitConverter ::ToString $PBKDF2 AES256 key -replace "-","" $PBKDF2 AES128 key string = System.BitConverter ::ToString $PBKDF2 AES128 key -replace "-","" Write-Verbose "PBKDF2 AES128 Key: $PBKDF2 AES128 key string" Write-Verbose "PBKDF2 AES256 Key: $PBKDF2 AES256 key string" $AES = New-Object "System.Security.Cryptography.AesManaged" $AES.Mode = System.Security.Cryptography.CipherMode ::CBC $AES.Padding = System.Security.Cryptography.PaddingMode ::None $AES.IV = $IV AES 256 $AES.KeySize = 256 $AES.Key = $PBKDF2 AES256 key $AES encryptor = $AES.CreateEncryptor $AES256 key part 1 = $AES encryptor.TransformFinalBlock $AES256 constant,0,$AES256 constant.Length $AES256 key part 2 = $AES encryptor.TransformFinalBlock $AES256 key part 1,0,$AES256 key part 1.Length $AES256 key = $AES256 key part 1 0..15 + $AES256 key part 2 0..15 $AES256 key string = System.BitConverter ::ToString $AES256 key -replace "-","" AES 128 $AES.KeySize = 128 $AES.Key = $PBKDF2 AES128 key $AES encryptor = $AES.CreateEncryptor $AES128 key = $AES encryptor.TransformFinalBlock $AES128 constant,0,$AES128 constant.Length $AES128 key string = System.BitConverter ::ToString $AES128 key -replace "-","" switch $OutputType { 'AES' { Write-Output "AES128 Key: $AES128 key string" Write-Output "AES256 Key: $AES256 key string" } 'AES128' { Write-Output "$AES128 key string" } 'AES256' { Write-Output "$AES256 key string" } 'AES128ByteArray' { Write-Output $AES128 key } 'AES256ByteArray' { Write-Output $AES256 key } } }