The Wayback Machine - https://web.archive.org/web/20201111202547/https://github.com/PowerShell/PowerShell/issues/1654
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConvertFrom-SecureString is broken on Linux #1654

Closed
Krishna-Vutukuri opened this issue Aug 4, 2016 · 62 comments
Closed

ConvertFrom-SecureString is broken on Linux #1654

Krishna-Vutukuri opened this issue Aug 4, 2016 · 62 comments

Comments

@Krishna-Vutukuri
Copy link
Contributor

@Krishna-Vutukuri Krishna-Vutukuri commented Aug 4, 2016

Steps to reproduce

  1. Install PowerShell on Ubuntu 14.04
  2. Launch PowerShell
  3. Run the following:
   $password = Convertto-Securestring -String "PowerShellRocks!" -AsPlainText -Force
   ConvertFrom-SecureString $password  

Expected behavior

No error

Actual behavior

The following error is thrown

PS /home/chythu/temp> ConvertFrom-SecureString $password                        ConvertFrom-SecureString : Unable to load DLL 'CRYPT32.dll': The specified
module could not be found.
 (Exception from HRESULT: 0x8007007E)
At line:1 char:1
- ConvertFrom-SecureString $password
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  - CategoryInfo          : NotSpecified: (:) [ConvertFrom-SecureString], Dl
    lNotFoundException
  - FullyQualifiedErrorId : System.DllNotFoundException,Microsoft.PowerShell
    .Commands.ConvertFromSecureStringCommand

Environment data

Name                           Value
---
PSVersion                      5.1.10032.0
PSEdition                      PowerShellCore
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   3.0.0.0
GitCommitId                    v6.0.0-alpha.7
CLRVersion
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Updates by @TravisEz13 on 2016-04-10

Environment data

> $PSVersionTable
Name                           Value                                           
----                           -----                                           
PSVersion                      6.0.2                                           
PSEdition                      Core                                            
GitCommitId                    v6.0.2                                          
OS                             Darwin 17.5.0 Darwin Kernel Version 17.5.0: M...
Platform                       Unix                                            
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                         
PSRemotingProtocolVersion      2.3                                             
SerializationVersion           1.1.0.1                                         
WSManStackVersion              3.0                                             

Workaround

The following works

# you should generate your own key
$Key = (3,4,2,3,56,34,254,222,1,1,2,23,42,54,33,233,1,34,2,7,6,5,35,43)       
$s  | ConvertFrom-SecureString -Key $Key                                      
@Krishna-Vutukuri Krishna-Vutukuri added this to the 6.0.0-Alpha.10 milestone Aug 4, 2016
@hiteshraigandhi
Copy link
Contributor

@hiteshraigandhi hiteshraigandhi commented Aug 10, 2016

Talked @KrishnaV-MSFT This is not needed for Azure demo. Moving it out of Alpha.10

@hiteshraigandhi hiteshraigandhi modified the milestones: Future, 6.0.0-Alpha.10 Aug 10, 2016
@jaredmichaelwilliams
Copy link

@jaredmichaelwilliams jaredmichaelwilliams commented Aug 18, 2016

Came across the same error on MacOS 10.12 Beta (16A270f)

Was just messing around got this:

PS> $User="Jared"
PS> $PWord = ConvertTo-SecureString –String "TestString" –AsPlainText -Force   
PS> $Cred = New-Object -TypeName "System.Management.Automation.PSCredential" –ArgumentList $User, $PWord
PS> ConvertFrom-SecureString -SecureString ($Cred.Password)

Result:

ConvertFrom-SecureString : Unable to load DLL 'CRYPT32.dll': The specified module could not be found.
 (Exception from HRESULT: 0x8007007E)
At line:1 char:1
+ ConvertFrom-SecureString -SecureString ($Cred.Password)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [ConvertFrom-SecureString], DllNotFoundException
    + FullyQualifiedErrorId : System.DllNotFoundException,Microsoft.PowerShell.Commands.ConvertFromSecureStringComman
@35359595
Copy link

@35359595 35359595 commented Oct 2, 2016

Hi,

same library error when trying to use mapped cert: psdrive:

Get-ChildItem Cert:/LocalMachine/

Error:

get-childitem : Unable to load DLL 'crypt32.dll': The specified module could not be found.
(Exception from HRESULT: 0x8007007E)
At line:1 char:1

  • get-childitem Cert:/LocalMachine/
  • - CategoryInfo          : NotSpecified: (:) [Get-ChildItem], DllNotFoundException
    - FullyQualifiedErrorId : System.DllNotFoundException,Microsoft.PowerShell.Commands.GetChildItemCommand
    
@vors vors added the OS-macOS label Oct 2, 2016
@vors
Copy link
Collaborator

@vors vors commented Oct 2, 2016

@35359595 good finding! The error definitely should be friendlier. On Linux and macOS Cert:/ provider needs some re-thinking. The way these two systems approach storing certificates are completely different from each other and windows.

@ChrisMagnuson
Copy link

@ChrisMagnuson ChrisMagnuson commented Jan 4, 2017

Fyi, 16.04.1 with PowerShell v6 alpha 14 still has this same issue

@ngetchell
Copy link

@ngetchell ngetchell commented Feb 12, 2017

This is holding me back from bringing my modules over to Linux. I'd like to be able to store Web API keys securely on all OSes, not just Windows.

@joeyaiello
Copy link
Member

@joeyaiello joeyaiello commented Feb 13, 2017

This is something we'll only be able to enable with the .NET Standard 2.0 APIs that bring back SecureString:

@daxian-dbw
Copy link
Member

@daxian-dbw daxian-dbw commented Apr 13, 2017

ConvertFrom-SecureString and ConvertTo-SecureString depend on System.Security.Cryptography.ProtectedData, which is still not available in netstandard2.0.
So these 2 cmdlets need to be re-worked on Unix platforms.

@daxian-dbw daxian-dbw removed their assignment Apr 13, 2017
@SteveL-MSFT SteveL-MSFT modified the milestones: 6.0.0-beta2, 6.0.0-beta1 Apr 13, 2017
@splatteredbits
Copy link

@splatteredbits splatteredbits commented Jan 23, 2019

Until this gets fixed, here's code to securely pass a credential to a background job:


$credentialKey = New-Object 'byte[]' (256/8)
$rng = New-Object 'Security.Cryptography.RNGCryptoServiceProvider'
$rng.GetBytes($credentialKey)

$serializableCredential = [pscustomobject]@{ 
                                                UserName = $credential.UserName;
                                                Password = ConvertFrom-SecureString -SecureString $credential.Password -Key $credentialKey
                                            }

$job = Start-Job {
    param(
        [Parameter(Mandatory)]
        [byte[]]
        $Key
    )
    $serializedCredential = $using:serializableCredential

    $password = ConvertTo-SecureString -String $serializedCredential.Password -Key $Key
    $credential = New-Object 'PSCredential' ($serializedCredential.UserName,$password)
    [Array]::Clear($Key,0,$Key.Length)
} -ArgumentList (,$credentialKey) | Wait-Job | Receive-Job

[Array]::Clear($credentialKey,0,$credentialKey.Length)
   
@vchrizz
Copy link

@vchrizz vchrizz commented Feb 5, 2019

Password = ConvertFrom-SecureString -SecureString $credential.Password -Key $credentialKey

how is this supposed to work if this has an issue itself?

anyways, tried your script though but got error:

ConvertFrom-SecureString : Cannot bind argument to parameter 'SecureString' because it is null.
At /home/myusername/powershell.ps1:7 char:99
+ ... = ConvertFrom-SecureString -SecureString $credential.Password -Key $c ...
+                                              ~~~~~~~~~~~~~~~~~~~~

so i tried to define username and password in a variable but:

ConvertFrom-SecureString : Cannot bind parameter 'SecureString'. Cannot convert the "testpassword" value of type "System.String" to type "System.Security.SecureString".
autocloudarc pushed a commit to autocloudarc/0026-azure-automation-plus-dsc-lab that referenced this issue Mar 1, 2019
@KKomarov
Copy link

@KKomarov KKomarov commented Mar 14, 2019

Why there is no separate issue for passing secure string over psremote? All opened issues closed as duplicates of this. In my opinion problem is different.
PSRemote hangs during key exchange due to lack of CryptoAPI implementation on Linux.
Who interested it hangs here

_keyExchangeCompleted.WaitOne();

Btw, we can add exception handler showing message that securestring not supported yet ^ it's quite hard to realise it related to securestrings if it hangs like that.
I think psremoting can be fixed without fixing ConvertFrom-SecureString commandlet, because we don't need to store keys on machine for later use. We need only generate rsa 2048 key pair, crypt/decrypt using rsa, crypt decrypt using AES CBC crossplatform.

Some good news there is crossplatform workaround.
Workaround for PSRemoting
Use python fresh implementation of PSRP pypsrp it supports securestrings!

@iSazonov
Copy link
Collaborator

@iSazonov iSazonov commented Mar 14, 2019

@KKomarov Please open new issue with repo steps and your suggestion.

@SteveL-MSFT
Copy link
Member

@SteveL-MSFT SteveL-MSFT commented Mar 15, 2019

@KKomarov the hang has been fixed in PSCore6.2-RC as part of #8723 already. The ability to actually send secure strings over for non-Windows should be a separate issue.

@JustinGrote
Copy link

@JustinGrote JustinGrote commented Mar 19, 2019

@iSazonov

DE0001: SecureString shouldn't be used
https://github.com/dotnet/platform-compat/blob/master/docs/DE0001.md#de0001-securestring-shouldnt-be-used

While that's nice in a perfect ivory tower world, in Powershell we are constantly gluing things together and that requires authenticating in whatever format that application requires, be it rest API, legacy application that only supports Basic authenticaiton, etc. We can't just simply "use windows credentials or certificates" for everything as this recommendation states, that's a nice recommendation for developing a new app, but not what we use powershell for.

It's not like PSCredential is going anywhere which is an implementation of SecureString, so until we have something in .net core that can use a TPM to encrypt keys or something, we need a "good enough" option.

Something like using AES256 and having the encryption key be a 600 permission-ed file on the non-windows file system is a possible start, not much worse than using the Crypto API in Windows

@iSazonov
Copy link
Collaborator

@iSazonov iSazonov commented Mar 20, 2019

I added the link for information only.

Essentially:

  1. It is impossible to port SecureString because System.Security.Cryptography.ProtectedData is Windows-only. There is no plans to port the API. Core team deprecate the API.
  2. We can keep backward compatibility for SecureString on Windows (including remoting)
  3. PowerShell Core must remain flexible and allow to work with legacy applications.
  4. It is acceptable to use basic authentication in protected environment
  5. Main problem how to detect protected environment vs public environment and what to do (prevent basic authentication, only warn, ...).
@SteveL-MSFT
Copy link
Member

@SteveL-MSFT SteveL-MSFT commented Mar 20, 2019

Early on, the @PowerShell/powershell-committee discussed introducing a SensitiveString to replace the functional need of SecureString even though both are not secure (the SecureString type would still be needed for backwards compat). A type (whether "Sensitive" or "Secure" is needed to indicate to PowerShell to prompt without echoing the input so it's used more than just for remoting. As for the original issue of this bug, this has been fixed (you don't get an error anymore), just keep in mind the SecureString is internally in plain text.

Windows PowerShell compatibility (.NET Standard 2.0) automation moved this from Priority-High to Done Mar 20, 2019
@vchrizz
Copy link

@vchrizz vchrizz commented Mar 21, 2019

thanks for the update, looks promising!
may we ask for an approximately timeframe when to expect to be able to utilize this (e.g. in microsoft-debian-stretch-prod debian repository)?

@rmbolger
Copy link

@rmbolger rmbolger commented Mar 21, 2019

As for the original issue of this bug, this has been fixed (you don't get an error anymore), just keep in mind the SecureString is internally in plain text.

Does anyone have a link to the fix or know what release version it will be available in? I'm still getting crypt32.dll errors in powershell_6.1.3-1.ubuntu.16.04_amd64.deb (same deal with the 6.2.0-rc.1 preview package).

I'm also curious how this fix affects Import/Export-CliXml when the data to be serialized contains SecureString or PSCredential objects.

@iSazonov
Copy link
Collaborator

@iSazonov iSazonov commented Mar 21, 2019

@rmbolger Could you please check with latest build (6.2.0-RC)?

@rkeithhill
Copy link
Contributor

@rkeithhill rkeithhill commented Mar 21, 2019

I'm seeing the same as @rmbolger

/home/hillr
03-20 23:44:55 31ms 11> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.2.0-rc.1
PSEdition                      Core
GitCommitId                    6.2.0-rc.1
OS                             Linux 4.4.0-17763-Microsoft #379-Microsoft Wed Mar 06 19:16:00 PST 2019
Platform                       Unix
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

/home/hillr
03-21 00:47:45 35ms 12> ConvertFrom-SecureString -SecureString $ss
ConvertFrom-SecureString : Unable to load shared library 'CRYPT32.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libCRYPT32.dll: cannot open shared object file: No such file or directory
At line:1 char:1
+ ConvertFrom-SecureString -SecureString $ss
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [ConvertFrom-SecureString], DllNotFoundException
+ FullyQualifiedErrorId : System.DllNotFoundException,Microsoft.PowerShell.Commands.ConvertFromSecureStringCommand
@SteveL-MSFT SteveL-MSFT reopened this Mar 21, 2019
@iSazonov
Copy link
Collaborator

@iSazonov iSazonov commented Mar 21, 2019

The cmdlets load directly the CRYPT32.dll

exportedString = SecureStringHelper.Protect(SecureString);

protectedData = ProtectedData.Protect(data, null,

if (!CAPI.CryptProtectData(new IntPtr(&dataIn),

internal static extern bool CryptProtectData(

@SteveL-MSFT SteveL-MSFT self-assigned this Mar 21, 2019
@SteveL-MSFT SteveL-MSFT mentioned this issue Mar 22, 2019
8 of 11 tasks complete
TravisEz13 added a commit that referenced this issue Mar 23, 2019
On Unix systems, fallback to plaintext manipulation instead of using the DPAPI which is not available.

## PR Context

Currently, existing scripts that use SecureString cmdlets fail with an error complaining about crypt32.dll not being available.  This change allows these cmdlets to be used, but there is no encryption of the string.
.Net already [states](https://docs.microsoft.com/en-us/dotnet/api/system.security.securestring?view=netcore-2.1#remarks) that the contents of a SecureString are not encrypted on .Net Core.

Fix #1654

Co-authored-by: Travis Plunk <travis.plunk@microsoft.com>
TravisEz13 added a commit that referenced this issue Mar 25, 2019
On Unix systems, fallback to plaintext manipulation instead of using the DPAPI which is not available.

## PR Context

Currently, existing scripts that use SecureString cmdlets fail with an error complaining about crypt32.dll not being available.  This change allows these cmdlets to be used, but there is no encryption of the string.
.Net already [states](https://docs.microsoft.com/en-us/dotnet/api/system.security.securestring?view=netcore-2.1#remarks) that the contents of a SecureString are not encrypted on .Net Core.

Fix #1654

Co-authored-by: Travis Plunk <travis.plunk@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

You can’t perform that action at this time.
Morty Proxy This is a proxified and sanitized view of the page, visit original site.