secure plain password example encrypt credential convertto powershell credentials

plain - powershell secure password



Guardado de credenciales para su reutilización por powershell y error ConvertTo-SecureString: clave no válida para uso en estado especificado (4)

Estaba haciendo algo como lo que se describe en esta publicación para guardar las credenciales en un archivo protegido para que nuestro proceso automatizado pueda usarlo para ejecutar scripts de PS remotos a través de Invoke-command: http://blogs.technet.com/b/robcost/archive/2008/05/01/powershell-tip-storing-and-using-password-credentials.aspx

Esto funciona muy bien cuando ejecuto esto en mi cuenta: la contraseña se lee desde un archivo cifrado, se pasa a Invocar-comando y todo está bien.

Hoy, cuando mi script estaba listo para su horario de máxima audiencia, intenté ejecutarlo en la cuenta de Windows que usará el proceso automatizado y obtuve este error a continuación mientras mi script intentaba leer la contraseña segura de un archivo:

ConvertTo-SecureString : Key not valid for use in specified state. At //remoted/script.ps1:210 char:87 + $password = get-content $PathToFolderWithCredentials/pass.txt | convertto-sec urestring <<<< + CategoryInfo : InvalidArgument: (:) [ConvertTo-SecureString], C ryptographicException + FullyQualifiedErrorId : ImportSecureString_InvalidArgument_Cryptographic Error,Microsoft.PowerShell.Commands.ConvertToSecureStringCommand

Le pedí a mi compañero de trabajo que corriera bajo su cuenta y obtuvo el mismo error.

Este es el código que estoy usando para guardar las credenciales:

$PathToFolderWithCredentials = "//path/removed" write-host "Enter login as domain/login:" read-host | out-file $PathToFolderWithCredentials/login.txt write-host "Enter password:" read-host -assecurestring | convertfrom-securestring | out-file $PathToFolderWithCredentials/pass.txt write-host "*** Credentials have been saved to $pathtofolder ***"

Este es el código del script que se ejecuta por proceso automatizado para leerlos y usarlos en Invoke-command:

$login= get-content $PathToFolderWithCredentials/login.txt $password = get-content $PathToFolderWithCredentials/pass.txt | convertto-securestring $credentials = new-object -typename System.Management.Automation.PSCredential -argumentlist $login,$password

Se produce un error en la línea $ password = get-content $ PathToFolderWithCredentials / pass.txt | convertto-securestring

¿Algunas ideas?


Debe crear la cadena de contraseña en la misma computadora y con el mismo nombre de usuario que usará para ejecutarla.


Lo siguiente permitirá que las credenciales se guarden como un archivo, luego esas credenciales serán utilizadas por otra secuencia de comandos ejecutada por un usuario diferente, de forma remota.

El código fue tomado de un gran artículo producido por David Lee, con solo algunos ajustes menores de mí mismo https://blog.kloud.com.au/2016/04/21/using-saved-credentials-securely-in-powershell-scripts/

El primer paso es guardar una contraseña segura en un archivo usando AES. Lo siguiente se ejecutará como un script independiente:

# Prompt you to enter the username and password $credObject = Get-Credential # The credObject now holds the password in a ‘securestring’ format $passwordSecureString = $credObject.password # Define a location to store the AESKey $AESKeyFilePath = “aeskey.txt” # Define a location to store the file that hosts the encrypted password $credentialFilePath = “credpassword.txt” # Generate a random AES Encryption Key. $AESKey = New-Object Byte[] 32 [Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($AESKey) # Store the AESKey into a file. This file should be protected! (e.g. ACL on the file to allow only select people to read) Set-Content $AESKeyFilePath $AESKey # Any existing AES Key file will be overwritten $password = $passwordSecureString | ConvertFrom-SecureString -Key $AESKey Add-Content $credentialFilePath $password

Luego, en su script donde necesita usar credenciales, use lo siguiente:

#set up path and user variables $AESKeyFilePath = “aeskey.txt” # location of the AESKey $SecurePwdFilePath = “credpassword.txt” # location of the file that hosts the encrypted password $userUPN = "domain/userName" # User account login #use key and password to create local secure password $AESKey = Get-Content -Path $AESKeyFilePath $pwdTxt = Get-Content -Path $SecurePwdFilePath $securePass = $pwdTxt | ConvertTo-SecureString -Key $AESKey #crete a new psCredential object with required username and password $adminCreds = New-Object System.Management.Automation.PSCredential($userUPN, $securePass) #use the $adminCreds for some task some-Task-that-needs-credentials -Credential $adminCreds

Tenga en cuenta que si el usuario puede acceder al archivo de contraseña y al archivo de clave, puede descifrar la contraseña del usuario.


Otro enfoque sería proteger los datos utilizando el alcance ''LocalMachine'' en lugar de ''CurrentUser'', que es el que usa ConvertFrom-SecureString.

public static string Protect(SecureString input, DataProtectionScope dataProtectionScope = DataProtectionScope.CurrentUser, byte[] optionalEntropy = null) { byte[] data = SecureStringToByteArray(input); byte[] data2 = ProtectedData.Protect(data, optionalEntropy, dataProtectionScope); for (int i = 0; i < data.Length; i++) { data[i] = 0; } return ByteArrayToString(data2); } private static byte[] SecureStringToByteArray(SecureString s) { var array = new byte[s.Length * 2]; if (s.Length > 0) { IntPtr intPtr = Marshal.SecureStringToGlobalAllocUnicode(s); try { Marshal.Copy(intPtr, array, 0, array.Length); } finally { Marshal.FreeHGlobal(intPtr); } } return array; } private static string ByteArrayToString(byte[] data) { var stringBuilder = new StringBuilder(); for (int i = 0; i < data.Length; i++) { stringBuilder.Append(data[i].ToString("x2", CultureInfo.InvariantCulture)); } return stringBuilder.ToString(); }

La cadena cifrada puede ser utilizada por ConvertTo-SecureString que está utilizando el alcance ''Usuario actual''.


ConvertFrom-SecureString toma un parámetro Key (y SecureKey ). Puede especificar la clave para guardar la cadena estándar encriptada y luego usar la clave nuevamente en ConvertTo-SecureString para recuperar la cadena segura, independientemente de la cuenta del usuario.

http://technet.microsoft.com/en-us/library/dd315356.aspx

En un proyecto, he implementado el cifrado asimétrico, mediante el cual las personas cifran la contraseña usando la clave pública y el proceso de automatización tiene la clave privada para descifrar las contraseñas: manejo de contraseñas en configuración de producción para implementación automatizada