I’ve been interfacing PowerShell scripts with APIs lately and have identified a need for securing my credentials at rest for those applications that require sending authenticated headers. My solution performs the base64 encoding transform, commonly required by web-based APIs, on string input provided at run time and stores it as an encrypted standard string for later use. This process is not straightforward which is odd, considering the obvious need for such obfuscation. I hope this write-up will assist spreading reasonable security practices on professional networks.
Before getting into the code, here are some things to note:
- I am not a security expert, nor am I a programmer, I specialize in Enterprise class systems and networks and, as such, write and maintain libraries of: maintenance; data manipulation; and reporting scripts.
- This is NOT considered a secure solution in and of itself, it is just a way to prevent password credentials being stored in plain-text
When executed the snippet below will:
- Prompt the user for a password, accepting the input as a secure string and storing it in the $password variable
- Convert the secure $password variable back to text
- Perform the required base64 encoding on the $password string
- Encrypt the base64 encoded string
- Save the encrypted string to a file for use in your API calls
$apiAuthorizationString = "C:\zScripts\APICreds1.txt"
[Byte[]] $hashKey = (1..16)
$user = "USERNAME"
$password = ([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR((Read-Host -Prompt "Enter Password" -AsSecureString)))
$password = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($password)
$authInfo = ("{0}:{1}" -f $user,$password)
$authInfo = [System.Text.Encoding]::UTF8.GetBytes($authInfo)
$authInfo = [System.Convert]::ToBase64String($authInfo)
$secureAPIString = ConvertTo-SecureString -AsPlainText $authInfo -Force
ConvertFrom-SecureString $secureAPIString -Key $hashKey | out-file $apiAuthorizationString -Force
$authInfo = $null
$password = $null
$secureAPIString = $null
To retrieve your base64 encoded string for API authentication simply import the encrypted standard string, convert it back to a plain-text string, and add it to your authorization header for use.
$APIAuthenticationString = get-content "C:\TEMP\APICreds1.txt"
[Byte[]] $hashKey = (1..16)
$authInfo = (New-Object System.Net.NetworkCredential("", (ConvertTo-SecureString -k ($hashKey) $APIAuthenticationString))).Password
$headers = @{Authorization=("Basic {0}" -f $authInfo)}
Stay tuned, my next article will utilize this technique to interface with the Pulse Secure Appliance API.
As a holistic information fiduciary David leverages proven industry standards and best practices that will optimize your processes and systems to maximize performance and minimize complexity. David has managed projects in varying phases of development, be it greenfield builds or forklift moves, backup design and architecture, infrastructure monitoring and alerting, scripting and automation, communications and network infrastructure, policy review and auditing, rack and stacks and virtualization.
He doesn't just get IT, he groks IT.