Подтвердить что ты не робот

Сохранение учетных данных для повторного использования с помощью powershell и ошибки ConvertTo-SecureString: ключ недействителен для использования в указанном состоянии

Я делал что-то вроде описанного в этом сообщении, чтобы сохранить учетные данные в защищенном файле, чтобы наш автоматизированный процесс мог использовать это для запуска удаленных сценариев PS через Invoke-command: http://blogs.technet.com/b/robcost/archive/2008/05/01/powershell-tip-storing-and-using-password-credentials.aspx

Это отлично работает, когда я запускаю его под своей учетной записью - пароль считывается из зашифрованного файла, передается команде Invoke-command и все в порядке.

Сегодня, когда мой script был готов в основное время, я попытался запустить его под учетной записью Windows, которая будет использоваться автоматическим процессом и получит эту ошибку ниже, пока мой script пытался прочитать защищенный пароль с файл:

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

Попросил моего товарища по работе выполнить его учетную запись, и он получил ту же ошибку.

Это код, который я использую для сохранения учетных данных:

$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 ***"

Это код в script для запуска автоматическим процессом, чтобы прочитать их для использования в команде Invoke:

$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

Ошибка происходит в строке $password = get-content $PathToFolderWithCredentials\pass.txt | ConvertTo-SecureString

Любые идеи?

4b9b3361

Ответ 1

ConvertFrom-SecureString принимает параметр KeySecureKey). Вы можете указать ключ для сохранения зашифрованной стандартной строки, а затем снова использовать ключ в ConvertTo-SecureString, чтобы вернуть защищенную строку, независимо от учетной записи использования.

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

В проекте я внедрил асимметричное шифрование, в котором люди шифруют пароль с использованием открытого ключа, а процесс автоматизации имеет закрытый ключ для расшифровки паролей: Обработка паролей в конфигурации производства для автоматическое развертывание

Ответ 2

Вам нужно создать строку пароля на том же компьютере и с тем же именем, которое вы будете использовать для ее запуска.

Ответ 3

Другим подходом было бы защитить данные, используя область "LocalMachine" вместо "CurrentUser", которая используется в 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();
}

Зашифрованная строка может использоваться ConvertTo-SecureString, которая использует область "CurrentUser".