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.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.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
}
}
}
source & further reading
gist.github.com — original article
OpenCode AI config to deny read access to .env, node_modules, build artifacts, cache dirs and ask before bash execution
Download CapCut Pro 2026 for Mac
For Agentic Coding