Forum Discussion

calvinrafael's avatar
calvinrafael
Copper Contributor
Aug 16, 2024

Powershell masking password

Hello Everyone,

 

I have the script (API POST) below which is working fine.

 

$UserPass = "username:password"

 

[string]$stringToEncode=$UserPass

$encodedString=[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($stringToEncode))

 

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"

$headers.Add("content-type", "application/json")

$headers.Add("accept", "application/json")

$headers.Add("Authorization", "Basic " + $encodedString)

 

Invoke-RestMethod -Uri "https://api_base_url/session" -Headers $headers -Method POST

 

I want to mask the password instead of plain text. So modified it to below which will ask to enter the masked password.

 

$UserPass = "username:$(Read-Host -Prompt "Please type the password" -AsSecureString)"

 

But the whole script is not working anymore. When I troubleshoot, there is a difference in encoding/decoding. I ran an online base64 decode and encode, the result is different.

 

Plain text password - username:password

dXNlcm5hbWU6cGFzc3dvcmQ= ---> username:password

 

Masked password - username:$(Read-Host -Prompt "Please type the password" -AsSecureString)

dXNlcm5hbWU6U3lzdGVtLlNlY3VyaXR5LlNlY3VyZVN0cmluZw== ---> username:System.Security.SecureString

 

How can I mask the password but able to read the System.Security.SecureString as the actual password?

 

Thank you in advanced.

 

2 Replies

  • LainRobertson's avatar
    LainRobertson
    Silver Contributor

    calvinrafael 

     

    Hi, Roel.

     

    A secure string is encrypted, not simply encoded (which is what base64 conversion is). You cannot easily read a secure string a plain text - which is by design (or it wouldn't be particularly secure, and barely even obscure).

     

    There are various ways to coerce the SecureString value back to plain text, where the easiest is to leverage the built-in [pscredential] class.

     

    Note: Secure string objects are not portable between machines. I mention this solely because I've seen people in the past try to save them on the machine they've generated them, port the script and saved encrypted password to another machine and wonder why it doesn't work. It's not meant to, so don't try.

     

    Example

    # Replace this line from your script/forum post.
    $UserPass = "username:$(Read-Host -Prompt "Please type the password" -AsSecureString)"
    
    # With these lines. Note: The username parameter in the pscredential constructor is ignored in this example, meaning it can be any value.
    $Password = Read-Host -Prompt "Enter password" -AsSecureString;
    $Credential = [pscredential]::new("Foo", $Password);
    $UserPass = "username:$($Credential.GetNetworkCredential().Password)";

     

     

    Cheers,

    Lain

     

    • calvinrafael's avatar
      calvinrafael
      Copper Contributor

      LainRobertson I really appreciate your help and response. Thanks for your code.

      Adding  below code works for me.

       

      $password = (Read-Host -Prompt "Please type the password" -AsSecureString)

       

      $Ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($password)

      $result = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($Ptr)

      [System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($Ptr)

      #$result

       

      $UserPass = "username:$($result)"

       

      [string]$stringToEncode=$UserPass

      $encodedString=[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($stringToEncode))

       

      [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

      $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"

      $headers.Add("content-type", "application/json")

      $headers.Add("accept", "application/json")

      $headers.Add("Authorization", "Basic " + $encodedString)

Resources