How does one securely handle passwords in a custom written PowerShell cmdlet?

后端 未结 5 702
没有蜡笔的小新
没有蜡笔的小新 2021-01-22 16:43

Assume I have a custom PowerShell Cmdlet that exports data and encrypts it using a password.

[Cmdlet(VerbsData.Export, \"SampleData\")]
public class ExportSample         


        
相关标签:
5条回答
  • 2021-01-22 17:03

    If you only want to obtain the password, you can use

    Read-Host cmdlet with the–asSecureString parameter.

    This parameter mask the input.

    0 讨论(0)
  • 2021-01-22 17:11

    Change the type of the Password parameter to SecureString; if the administrator omits the -Password parameter, PowerShell will do the right thing by prompting the administrator for the mandatory parameter and display astrisks as they type.

    Ideally the implementation of your cmdlet will pass the SecureString to some API that natively supports SecureString (most secure); if not, you'll have to extract the password from the SecureString. Here's a good article on how to do that: How to properly convert SecureString to String

    0 讨论(0)
  • 2021-01-22 17:16

    SecureString-Handling gives you a feeling to be a bit more secure, even if this is not the case. You can easily encrypt any SecureString like this...

    $mrsh = [System.Runtime.InteropServices.Marshal]
    $ptr  = $mrsh::SecureStringToBSTR($secureString)
    $pass = $mrsh::PtrToStringAuto($ptr)
    

    or even without marshalling just with a webclient-object like this...

    $cred = Get-Credential
    $web = [Net.WebClient]::new()
    $web.Credentials = [System.Net.NetworkCredential]::new($cred.UserName,$cred.Password)
    $pass = $web.Credentials.Password 
    

    So, in sum neither the password nor the SecureString-Password should be stores permanently as a file or anything else. Make the lifetime of this information as short as possible - e.g. from entering the password till a cleanup of the password-variable and all its inherited variables like so:

    Remove-Variable pass, cred, web -ea 0 
    
    0 讨论(0)
  • 2021-01-22 17:24

    You can find in this answer a way to crypt with the computer password (works on safe machines).

    Using @Christian response you can put the password to the disk like this :

    PS > $cred.Password | ConvertFrom-SecureString | Set-Content c:\temp\password.txt
    

    And retreive it with :

    $password = Get-Content c:\temp\password.txt | ConvertTo-SecureString
    $cred = New-Object System.Management.Automation.PsCredential "UserName",$password
    
    0 讨论(0)
  • 2021-01-22 17:28

    If you are writing a C# PowerShell Cmdlet and one of the parameters requires the user to enter a password it should be obfuscated.

    To do this you need to be using System.Security;

    And then your parameter type should be SecureString.

    So using your example:

    [Cmdlet(VerbsData.Export, "SampleData")]
    public class ExportSampleData : PSCmdlet
    {
        [Parameter(Mandatory = true)]
        public SecureString Password
        {
            get;
            set;
        }
    
    /* additional parameters */
    }
    
    0 讨论(0)
提交回复
热议问题