Convertir une chaîne sécurisée en texte brut


87

Je travaille dans PowerShell et j'ai un code qui convertit avec succès un mot de passe saisi par l'utilisateur en texte brut:

$SecurePassword = Read-Host -AsSecureString  "Enter password" | convertfrom-securestring | out-file C:\Users\tmarsh\Documents\securePassword.txt

J'ai essayé plusieurs façons de le reconvertir, mais aucune d'entre elles ne semble fonctionner correctement. Plus récemment, j'ai essayé ce qui suit:

$PlainPassword = Get-Content C:\Users\tmarsh\Documents\securePassword.txt

#convert the SecureString object to plain text using PtrToString and SecureStringToBSTR
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PlainPassword)
$PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR) #this is an important step to keep things secure

Cela me donne également une erreur.

Cannot convert argument "s", with value: "01000000d08c9ddf0115d1118c7a00c04fc297eb0100000026a5b6067d53fd43801a9ef3f8ef9e43000000000200000000000366000
0c0000000100000008118fdea02bfb57d0dda41f9748a05f10000000004800000a000000010000000c50f5093f3b87fbf9ee57cbd17267e0a10000000833d1d712cef01497872a3457bc8
bc271400000038c731cb8c47219399e4265515e9569438d8e8ed", for "SecureStringToBSTR" to type "System.Security.SecureString": "Cannot convert the "01000000
d08c9ddf0115d1118c7a00c04fc297eb0100000026a5b6067d53fd43801a9ef3f8ef9e430000000002000000000003660000c0000000100000008118fdea02bfb57d0dda41f9748a05f10
000000004800000a000000010000000c50f5093f3b87fbf9ee57cbd17267e0a10000000833d1d712cef01497872a3457bc8bc271400000038c731cb8c47219399e4265515e9569438d8e8
ed" value of type "System.String" to type "System.Security.SecureString"."
At C:\Users\tmarsh\Documents\Scripts\Local Admin Script\PlainTextConverter1.ps1:14 char:1
+ $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($PlainPassw ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

Cannot find an overload for "PtrToStringAuto" and the argument count: "1".
At C:\Users\tmarsh\Documents\Scripts\Local Admin Script\PlainTextConverter1.ps1:15 char:1
+ $PlainPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodCountCouldNotFindBest

Cannot convert argument "s", with value: "", for "ZeroFreeBSTR" to type "System.IntPtr": "Cannot convert null to type "System.IntPtr"."
At C:\Users\tmarsh\Documents\Scripts\Local Admin Script\PlainTextConverter1.ps1:16 char:1
+ [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR) #this is an important ste ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodException
    + FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument

Password is:  01000000d08c9ddf0115d1118c7a00c04fc297eb0100000026a5b6067d53fd43801a9ef3f8ef9e430000000002000000000003660000c0000000100000008118fdea02bfb57d0dda41f97
48a05f10000000004800000a000000010000000c50f5093f3b87fbf9ee57cbd17267e0a10000000833d1d712cef01497872a3457bc8bc271400000038c731cb8c47219399e4265515e9569
438d8e8ed

Quelqu'un connaît-il un moyen qui fonctionnera pour cela?

Réponses:


115

Vous êtes proche, mais le paramètre que vous passez SecureStringToBSTRdoit être un SecureString. Vous semblez transmettre le résultat de ConvertFrom-SecureString, qui est une chaîne standard chiffrée. Alors appelez ConvertTo-SecureStringceci avant de passer à SecureStringToBSTR.

$SecurePassword = ConvertTo-SecureString $PlainPassword -AsPlainText -Force
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

4
Je suis content que ça marche. Faites attention avec votre chaîne, maintenant, il s'agit d'une variable de chaîne non sécurisée contenant probablement quelque chose d'important comme un mot de passe - il n'est plus sécurisé dans la mémoire de votre processus, etc.
— MatthewG

19
Selon la documentation Marshal.SecureStringToBSTR : Étant donné que cette méthode alloue la mémoire non managée requise pour une chaîne, libérez toujours le BSTR lorsque vous avez terminé en appelant la méthode ZeroFreeBSTR . Donc, vous devez d'exécuter ce qui suit à la fin: [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR).
— Rosberg Linhares

@RosbergLinhares - Puisque nous sommes (vraisemblablement) concentrés sur PowerShell, y a-t-il une raison pour laquelle vous ne pouvez pas simplement $BSTR = $null?
— Orangutech

3
@Orangutech Vous ne pouvez pas seulement définir la variable sur $null, car nous traitons ici d'objets non gérés. Vous n'obtiendrez pas d'erreur immédiatement, mais je pense que vous pourriez avoir des problèmes avec le temps.
— Rosberg Linhares

1
Mis à part la fuite de mémoire résultant de l'appel manquant à ZeroFreeBSTR(), comme indiqué, l'utilisation de PtrToStringAuto()était toujours conceptuellement défectueuse et - maintenant que PowerShell est multiplateforme - échoue sur les plates-formes de type Unix. Cela aurait toujours dû l'être PtrToStringBSTR() - voyez cette réponse .
— mklement0

81

Vous pouvez également utiliser PSCredential.GetNetworkCredential ():

$SecurePassword = Get-Content C:\Users\tmarsh\Documents\securePassword.txt | ConvertTo-SecureString
$UnsecurePassword = (New-Object PSCredential "user",$SecurePassword).GetNetworkCredential().Password

J'ai testé les deux méthodes et elles sont toutes les deux toujours correctes.
— Maximilian Burszley

10
J'ai voté pour cette solution car elle est plus Powershelly.
— Jim

1
À utiliser System.Management.Automation.PSCredentialdans les anciennes versions PS lorsque le nom de type court n'est pas reconnu.
— marsze

1
Shorter:[PSCredential]::new(0, $SecurePassword).GetNetworkCredential().Password
— majkinetor

Plus court:[System.Net.NetworkCredential]::new("", $SecurePassword).Password
— K. Frank

36

Le moyen le plus simple de le reconvertir dans PowerShell

[System.Net.NetworkCredential]::new("", $SecurePassword).Password

1
En effet, pas besoin de passer par PSCredential.
— Nicolas Melay

J'aime cette approche. Pour info pour les accros de compatibilité, cette prise de surcharge de constructeur a SecureStringété introduite dans .Net Framework 4.0. Sur PowerShell v2, j'ai essayé (New-Object -TypeName System.Net.NetworkCredential -ArgumentList "u",$SecureString).Passwordmais malheureusement, le SecureStringest silencieusement converti en String. L'appel semble réussir, mais la Passwordpropriété est alors la valeur littérale "System.Security.SecureString". Faites attention.
— John Rees le

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.