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

Open
Krishna-Vutukuri opened this Issue Aug 4, 2016 · 48 comments

Comments

@Krishna-Vutukuri
Contributor

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

@oising

This comment has been minimized.

@hiteshraigandhi

This comment has been minimized.

Contributor

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

This comment has been minimized.

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

This comment has been minimized.

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

This comment has been minimized.

Collaborator

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

This comment has been minimized.

ChrisMagnuson commented Jan 4, 2017

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

@ngetchell

This comment has been minimized.

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

This comment has been minimized.

Member

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

This comment has been minimized.

Member

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

@SteveL-MSFT

This comment has been minimized.

Member

SteveL-MSFT commented Jan 22, 2018

@iSazonov it's my understanding that SecureString depends on specific OS support which is not available on non-Windows and not part of the Windows Compatibility Pack.

We should provide a better error message even though this won't work.

@vchrizz

This comment has been minimized.

vchrizz commented Jan 22, 2018

Is there some possible alternative to the *-SecureString cmdlets on Unix if they will be removed?
Sorry if i missed it, give me a pointer on why it is not possible on unix. What is the missing "os-specific" part required on unix?
How else could one handle credentials to get them in the correct format and further use them?

@cenit

This comment has been minimized.

cenit commented Jan 22, 2018

I think this Issue on CoreFX sums it perfectly: dotnet/corefx#22510
It also seems that no progress is being done, unfortunately.

@vchrizz

This comment has been minimized.

vchrizz commented Jan 22, 2018

thanks, that explains it very well.

@iSazonov

This comment has been minimized.

Collaborator

iSazonov commented Jan 23, 2018

@SteveL-MSFT Using WCP assume using common pattern if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { ... }
If some API is absent in WCP we could feedback in WCP repo. But even without it we can use the common pattern combined with #if !UNIX.

@SteveL-MSFT

This comment has been minimized.

Member

SteveL-MSFT commented Jan 24, 2018

@iSazonov for this specific issue I don't believe WCP will solve this as the SecureString type is really an empty implementation on non-Windows.

@iSazonov

This comment has been minimized.

Collaborator

iSazonov commented Jan 24, 2018

I like it anyway. 😄

@Jaykul

This comment has been minimized.

Jaykul commented Jan 26, 2018

Ok, I'm editing this to make sure I got it straight...

  1. There was no SecureString implementation except on Windows.
  2. The PowerShell team mocked it, so they could avoid changing all their APIs that require it.
  3. Then the .NET team implemented it but only the short-term in-memory protection
  4. So trying to serialize a (in)SecureString crashes except on Windows, because the whole function is now Windows only, but is exposed everywhere...

Despite the early warning of this from 18 months ago

Despite the extremely clear message from the .Net Framework team 6 months ago.

🙄

@Jaykul

This comment has been minimized.

Jaykul commented Jan 26, 2018

The bottom line is that the .NET framework (and PowerShell) needs a cross-platform data protection library, because dev/ops need to store secrets didn't just suddenly disappear when we added new OSes to the mix, and it's not always practical to rely on web services like Azure KeyVault, RED Identity management, or Thycotic Secret Server. 😕

The .NET team is apparently not inclined to be particularly helpful here.

I know that ASP.NET wrote their own DataProtection stuff, but it's fairly weird and they recommend limiting it's use to specific scenarios...

What we need to know is:

Does the PowerShell team plan to create a cross-platform implementation of SecureString serialization?

If not, please remove the cmdlets that do not work at all, and provide a better error message for CliXML than the current, "oh darn, if only there was a Crypto dll available" error.

@psmulovics

This comment has been minimized.

psmulovics commented Jan 26, 2018

Check out related items:
NuGet/Home#1851
dotnet/corefx#6746

@iSazonov

This comment has been minimized.

Collaborator

iSazonov commented Jan 26, 2018

We could use ASP.NET DataProtection. This is the most reliable of what is available today. Especially as we need quite a bit.

@pcgeek86

This comment has been minimized.

pcgeek86 commented Mar 22, 2018

I'm trying to read a password securely, to pass into a MySQL command line. What's the recommended alternative, so that I'm not echoing passwords to the console as I type them?

Repro Steps

$str = Read-Host -AsSecureString
ConvertFrom-SecureString -SecureString $str

Result

ConvertFrom-SecureString : Unable to load DLL 'CRYPT32.dll': The specified module or one of its dependencies could not be found.
 (Exception from HRESULT: 0x8007007E)
At line:1 char:1
+ ConvertFrom-SecureString -SecureString $str
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [ConvertFrom-SecureString], DllNotFoundException
+ FullyQualifiedErrorId : System.DllNotFoundException,Microsoft.PowerShell.Commands.ConvertFromSecureStringCommand
@markekraus

This comment has been minimized.

Collaborator

markekraus commented Mar 22, 2018

@pcgeek86 This is one solution to get the Plain text string from a securestring on linux:

$str = Read-Host -AsSecureString
$plaintext = [System.Net.NetworkCredential]::new('',$str).Password
@TravisEz13

This comment has been minimized.

Member

TravisEz13 commented Apr 11, 2018

I added another workaround in the description

@ffeldhaus

This comment has been minimized.

Contributor

ffeldhaus commented Jun 7, 2018

Handling secrets on Linux seems to be quite a mess. There are many implementation efforts and outdated projects.

It seems Gnome is or was using the Secret Service API. libsecret seems to be a library to access secrets using the Secret Service bus.

Mac OS X allows to interact with the Keychain via the security command line utility or programmatically via the Keychain Services.

QtKeychain is an approach to create a platform independent password and secret manager for Linux (using libsecret), Mac OS X (using the Key Chain) and Windows (using the Windows Credential Store) and is probably closest to what is required for PowerShell. Could we use this as a starting point?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment