224 lines
8.7 KiB
PowerShell
224 lines
8.7 KiB
PowerShell
# Requires running as Administrator for cryptographic operations
|
|
Add-Type -AssemblyName System.Security
|
|
|
|
function Write-ByteArrayToFile {
|
|
param(
|
|
[string]$Path,
|
|
[byte[]]$ByteArray
|
|
)
|
|
|
|
try {
|
|
[System.IO.File]::WriteAllBytes($Path, $ByteArray)
|
|
Write-Host "Successfully wrote $($ByteArray.Length) bytes to $Path" -ForegroundColor Green
|
|
return $true
|
|
}
|
|
catch {
|
|
Write-Error "Failed to write file $Path : $($_.Exception.Message)"
|
|
return $false
|
|
}
|
|
}
|
|
|
|
function Generate-OEMKeys {
|
|
param(
|
|
[string]$OutputPath = ".",
|
|
[string]$PublicKeyName = "pubkey.blob",
|
|
[string]$PrivateKeyName = "prvkey.blob",
|
|
[int]$KeySize = 2048
|
|
)
|
|
|
|
# Resolve the output path to absolute path
|
|
$ResolvedOutputPath = Resolve-Path $OutputPath -ErrorAction SilentlyContinue
|
|
if (-not $ResolvedOutputPath) {
|
|
$ResolvedOutputPath = New-Item -ItemType Directory -Path $OutputPath -Force | Select-Object -ExpandProperty FullName
|
|
} else {
|
|
$ResolvedOutputPath = $ResolvedOutputPath.Path
|
|
}
|
|
|
|
$PublicKeyPath = Join-Path $ResolvedOutputPath $PublicKeyName
|
|
$PrivateKeyPath = Join-Path $ResolvedOutputPath $PrivateKeyName
|
|
|
|
Write-Host "Generating OEM public/private key pair..." -ForegroundColor Cyan
|
|
Write-Host "Output Folder: $ResolvedOutputPath" -ForegroundColor Yellow
|
|
Write-Host "Key Size: $KeySize bits" -ForegroundColor Yellow
|
|
Write-Host "Provider: MS_ENH_RSA_AES_PROV" -ForegroundColor Yellow
|
|
Write-Host "Algorithm: RSA Key Exchange" -ForegroundColor Yellow
|
|
|
|
try {
|
|
# Create RSA crypto service provider with specified parameters
|
|
$cspParams = New-Object System.Security.Cryptography.CspParameters
|
|
$cspParams.ProviderType = 24 # PROV_RSA_AES
|
|
$cspParams.KeyContainerName = "OEMDecryptContainer"
|
|
$cspParams.KeyNumber = 1 # AT_KEYEXCHANGE
|
|
$cspParams.Flags = [System.Security.Cryptography.CspProviderFlags]::UseMachineKeyStore
|
|
|
|
# Create RSA provider with enhanced AES provider
|
|
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider($KeySize, $cspParams)
|
|
|
|
Write-Host "RSA key generated successfully" -ForegroundColor Green
|
|
|
|
# Export public key blob (OOBE public key format)
|
|
Write-Host "`nExporting public key..." -ForegroundColor Cyan
|
|
$publicKeyBlob = $rsa.ExportCspBlob($false)
|
|
Write-Host "Public key blob size: $($publicKeyBlob.Length) bytes" -ForegroundColor Gray
|
|
|
|
# Export private key blob
|
|
Write-Host "Exporting private key..." -ForegroundColor Cyan
|
|
$privateKeyBlob = $rsa.ExportCspBlob($true)
|
|
Write-Host "Private key blob size: $($privateKeyBlob.Length) bytes" -ForegroundColor Gray
|
|
|
|
# Write keys to files
|
|
Write-Host "`nWriting keys to files..." -ForegroundColor Cyan
|
|
|
|
$publicResult = Write-ByteArrayToFile -Path $PublicKeyPath -ByteArray $publicKeyBlob
|
|
$privateResult = Write-ByteArrayToFile -Path $PrivateKeyPath -ByteArray $privateKeyBlob
|
|
|
|
if ($publicResult -and $privateResult) {
|
|
Write-Host "`nKey generation completed successfully!" -ForegroundColor Green
|
|
Write-Host "Public key saved to: $PublicKeyPath" -ForegroundColor White
|
|
Write-Host "Private key saved to: $PrivateKeyPath" -ForegroundColor White
|
|
|
|
# Display key information
|
|
Write-Host "`nKey Information:" -ForegroundColor Yellow
|
|
Write-Host "Key Size: $KeySize bits" -ForegroundColor Gray
|
|
Write-Host "Public Key Format: PUBLICKEYBLOB" -ForegroundColor Gray
|
|
Write-Host "Private Key Format: PRIVATEKEYBLOB" -ForegroundColor Gray
|
|
Write-Host "Compatible with: Windows OOBE Registration" -ForegroundColor Gray
|
|
|
|
return @{
|
|
PublicKeyPath = $PublicKeyPath
|
|
PrivateKeyPath = $PrivateKeyPath
|
|
OutputFolder = $ResolvedOutputPath
|
|
}
|
|
} else {
|
|
Write-Error "Failed to write one or more key files"
|
|
return $false
|
|
}
|
|
}
|
|
catch {
|
|
Write-Error "Key generation failed: $($_.Exception.Message)"
|
|
Write-Host "Ensure you are running PowerShell as Administrator" -ForegroundColor Red
|
|
return $false
|
|
}
|
|
finally {
|
|
# Clean up
|
|
if ($rsa) {
|
|
$rsa.Dispose()
|
|
}
|
|
}
|
|
}
|
|
|
|
function Get-KeyInformation {
|
|
param(
|
|
[string]$KeyPath
|
|
)
|
|
|
|
if (-not (Test-Path $KeyPath)) {
|
|
Write-Error "Key file not found: $KeyPath"
|
|
return
|
|
}
|
|
|
|
try {
|
|
$keyBlob = [System.IO.File]::ReadAllBytes($KeyPath)
|
|
Write-Host "Key File: $KeyPath" -ForegroundColor Cyan
|
|
Write-Host "File Size: $($keyBlob.Length) bytes" -ForegroundColor Gray
|
|
|
|
# Try to import and display basic info
|
|
$rsa = New-Object System.Security.Cryptography.RSACryptoServiceProvider
|
|
$rsa.ImportCspBlob($keyBlob)
|
|
|
|
Write-Host "Key Size: $($rsa.KeySize) bits" -ForegroundColor Gray
|
|
Write-Host "Public Only: $($rsa.PublicOnly)" -ForegroundColor Gray
|
|
|
|
$rsa.Dispose()
|
|
}
|
|
catch {
|
|
Write-Warning "Could not parse key file (may be normal for blob format): $($_.Exception.Message)"
|
|
}
|
|
}
|
|
|
|
function Show-FolderContents {
|
|
param([string]$FolderPath)
|
|
|
|
Write-Host "`nFolder Contents:" -ForegroundColor Cyan
|
|
Write-Host "================" -ForegroundColor Cyan
|
|
|
|
$files = Get-ChildItem -Path $FolderPath
|
|
foreach ($file in $files) {
|
|
Write-Host " $($file.Name) ($([math]::Round($file.Length/1KB, 2)) KB)" -ForegroundColor White
|
|
}
|
|
}
|
|
|
|
function Find-GeneratedKeys {
|
|
param(
|
|
[string]$SearchRoot = ".",
|
|
[string]$PublicKeyName = "pubkey.blob",
|
|
[string]$PrivateKeyName = "prvkey.blob"
|
|
)
|
|
|
|
$searchPath = Resolve-Path $SearchRoot
|
|
Write-Host "Searching for generated key files in: $searchPath" -ForegroundColor Cyan
|
|
|
|
$foundPublic = Get-ChildItem -Path $searchPath -Filter $PublicKeyName -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
$foundPrivate = Get-ChildItem -Path $searchPath -Filter $PrivateKeyName -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
|
|
|
|
if ($foundPublic -or $foundPrivate) {
|
|
Write-Host "`nFound key files:" -ForegroundColor Yellow
|
|
if ($foundPublic) {
|
|
Write-Host " Public Key: $($foundPublic.FullName)" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " Public Key: Not found" -ForegroundColor Red
|
|
}
|
|
if ($foundPrivate) {
|
|
Write-Host " Private Key: $($foundPrivate.FullName)" -ForegroundColor Green
|
|
} else {
|
|
Write-Host " Private Key: Not found" -ForegroundColor Red
|
|
}
|
|
} else {
|
|
Write-Host "No key files found in search path" -ForegroundColor Red
|
|
}
|
|
|
|
return @{
|
|
PublicKey = $foundPublic
|
|
PrivateKey = $foundPrivate
|
|
}
|
|
}
|
|
|
|
# Main execution
|
|
Write-Host "Windows OOBE OEM Key Generator" -ForegroundColor Magenta
|
|
Write-Host "================================" -ForegroundColor Magenta
|
|
|
|
# Get the current directory for reference
|
|
$currentDir = Get-Location
|
|
Write-Host "Current directory: $currentDir" -ForegroundColor Gray
|
|
|
|
# Generate the keys in the current directory
|
|
$result = Generate-OEMKeys -OutputPath "."
|
|
|
|
if ($result) {
|
|
Write-Host "`nVerifying generated keys..." -ForegroundColor Cyan
|
|
Get-KeyInformation -KeyPath $result.PublicKeyPath
|
|
Get-KeyInformation -KeyPath $result.PrivateKeyPath
|
|
|
|
# Show what's in the folder
|
|
Show-FolderContents -FolderPath $result.OutputFolder
|
|
|
|
Write-Host "`nNext Steps:" -ForegroundColor Yellow
|
|
Write-Host "1. Use the public key file for OOBE registration: $($result.PublicKeyPath)" -ForegroundColor White
|
|
Write-Host "2. Place the public key file in %systemroot%\system32\Oobe\Info\" -ForegroundColor White
|
|
Write-Host "3. Configure your Oobe.xml with registration settings" -ForegroundColor White
|
|
Write-Host "4. Keep the private key file secure: $($result.PrivateKeyPath)" -ForegroundColor Red
|
|
|
|
Write-Host "`nAll files are located in: $($result.OutputFolder)" -ForegroundColor Green
|
|
} else {
|
|
Write-Host "Key generation failed. Please check the errors above." -ForegroundColor Red
|
|
}
|
|
|
|
# Search for the generated files to confirm their location
|
|
Write-Host "`nConfirming file locations..." -ForegroundColor Cyan
|
|
Find-GeneratedKeys -SearchRoot "."
|
|
|
|
# Copy public key to the OOBE Info directory
|
|
$oobeInfoPath = ".\..\..\`$OEM`$\`$`$\System32\Oobe\Info"
|
|
write-Host "`nCopying public key to OOBE Info directory: $oobeInfoPath" -ForegroundColor Cyan
|
|
copy-item -Path $result.PublicKeyPath -Destination $oobeInfoPath -Force
|
|
Write-Host "Public key copied successfully." -ForegroundColor Green |