如何使用PowerShell保護密碼

 2023-10-18 阅读 17 评论 0

摘要:介紹 (Introduction) Do you have processes or scripts that require you to provide a password? Against the desires of your security officer, do you have to save those passwords in plain text, in your scripts? PowerShell offers a way that you can store a pa

介紹 (Introduction)

Do you have processes or scripts that require you to provide a password? Against the desires of your security officer, do you have to save those passwords in plain text, in your scripts? PowerShell offers a way that you can store a password or prompt the user for the information. You can then utilize that information to build what is known as a PSCredential. The majority of commands for PowerShell that support remote connections to servers (WMI, CIM, Invoke-Command, etc.), offer the ability to pass in a credential. While some only need the password, some need the full object to authenticate a user. This object in PowerShell can be made a few different ways based on your needs. I will go over a few options that are commonly used, but first lets discuss what makes up a PSCredential.

是否有要求您提供密碼的流程或腳本? 違反安全人員的要求,您是否必須將這些密碼以純文本格式保存在腳本中? PowerShell提供了一種存儲密碼或提示用戶輸入信息的方法。 然后,您可以利用該信息來構建所謂的PSCredential。 PowerShell的大多數命令都支持到服務器的遠程連接(WMI,CIM,Invoke-Command等),提供了傳遞憑據的功能。 雖然有些只需要密碼,但有些則需要完整的對象來認證用戶。 可以根據需要以幾種不同的方式將PowerShell中的此對象制成。 我將介紹一些常用的選項,但首先讓我們討論組成PSCredential的內容。

PSC憑證 (PSCredential)

The full type is “System.Management.Automation.PSCredential” object. Commands that utilize a “-Credential” parameter will generally require this type to be passed in. You have a few different ways to go about it based on your needs. Each method generally lines up to two different scenarios: interactive or automated. The PSCredential object requires two arguments:

完整類型為“ System.Management.Automation.PSCredential”對象。 使用“ -Credential”參數的命令通常需要傳遞此類型。根據您的需要,您可以通過幾種不同的方式進行處理。 每種方法通常最多可列出兩種不同的方案:交互式或自動化。 PSCredential對象需要兩個參數:

  • UserName (System.String)

    用戶名(System.String)
  • Password (System.Security.SecureString)

    密碼(System.Security.SecureString)

The username is pretty obvious, but that password is not just a string value. You cannot just take a string and declare it as a SecureString. In order to even build a SecureString means you have to provide a password. Based on how you do this it can pose a security risk in most environments, because you either pass in (or store) your password in plain text. When you are working with passwords in PowerShell it is best to obfuscate your password to protect against those folks with wandering eyes. PowerShell offers a few different options to hide the password. I will go over these below and provide a few examples.

用戶名很明顯,但是該密碼不僅僅是一個字符串值。 您不能只接受字符串并將其聲明為SecureString。 為了構建SecureString,還必須提供密碼。 根據您的操作方式,它可能會在大多數環境中帶來安全風險,因為您要么以純文本形式傳遞(或存儲)密碼。 當您在PowerShell中使用密碼時,最好對密碼進行混淆處理,以保護那些眼神游蕩的人。 PowerShell提供了一些不同的選項來隱藏密碼。 我將在下面詳細介紹這些示例。

一個小警告 (A small caveat)

When you work with PSCredential objects you will find that there is a way to read that password back as plain text. This object contains properties on a particular method, that will return the password back as plain text. The method is: GetNetworkCredential(). This method has four properties: Domain, Password, SecurePassword, and UserName. This is there because there could be times you work with commands or third party executables that you need to pass in that password as plain text. You can pull the property to do that without having to necessarily show it in your script as plain text.

當使用PSCredential對象時,您會發現有一種方法可以將該密碼以純文本形式讀回。 該對象包含特定方法的屬性,該屬性會將密碼作為純文本返回。 該方法是:GetNetworkCredential()。 此方法具有四個屬性:域, 密碼 ,SecurePassword和用戶名。 這是因為您有時可能需要使用命令或第三方可執行文件來以純文本形式輸入該密碼。 您可以拉動屬性來執行此操作,而不必在腳本中將其顯示為純文本。

That is all to say you just need to understand that while the methods being shown do work for meeting certain security requirements, understand the risk of leaving variables like this in memory once your script completes. It is best to get into the habit of cleaning up at the end. Anytime you use the methods below they need to be locally scoped to the specific function using it. I would also recommend using “Remove-Variable” to ensure the variable you capture the password in is cleared from memory once you are done with it.

就是說,您只需要了解所顯示的方法確實可以滿足某些安全性要求,但要了解腳本完成后將此類變量保留在內存中的風險。 最好養成最后清理的習慣。 每當您使用下面的方法時,都需要使用它們將它們局部限制在特定的功能范圍內。 我還建議您使用“ Remove-Variable”,以確保一旦完成捕獲操作,便會從內存中清除捕獲密碼的變量。

讀主機 (Read-Host)

Interactive commands mean you are going to prompt the user to enter some bit of information, like a password. Read-Host is useful to prompt for the password at the command line, especially if you don’t need the username as well. In order to get the SecureString object you just need to use the “-AsSecureString” parameter. This will show the password with asterisks as the user types, and will return a SecureString object.

交互式命令意味著您將提示用戶輸入一些信息,例如密碼。 Read-Host對于在命令行提示輸入密碼很有用,尤其是在您不需要用戶名的情況下。 為了獲得SecureString對象,您只需要使用“ -AsSecureString”參數即可。 這將在用戶鍵入時顯示帶有星號的密碼,并將返回SecureString對象。

?
$t = Read-Host -Prompt "Please enter your password" -AsSecureString$t.GetType()

獲取憑證 (Get-Credential)

Using this command will give the user a pop-up window they are likely more familiar with, to enter their username and password. The advantage you have with this command is after the user clicks the “Ok” button it will return a PSCredential object. This can save you a few more lines of code compared to the “Read-Host” command, that would still require you build the PSCredential object. This command is a favorite for one-liner commands where you need to quickly build a PSCredential object for a given command in PowerShell.

使用此命令將為用戶提供一個他們可能更熟悉的彈出窗口,以輸入用戶名和密碼。 使用此命令的好處是用戶單擊“確定”按鈕后,它將返回一個PSCredential對象。 與“ Read-Host”命令相比,這可以節省更多的代碼行,但仍然需要您構建PSCredential對象。 此命令是單行命令的常用命令,您需要為PowerShell中的給定命令快速構建PSCredential對象。

?
’’’powershell $t = Get-Credential -Message “Please enter your password” ```

After clicking OK we can see that a PSCredential object is returned.

單擊“確定”后,我們可以看到返回了PSCredential對象。

If you wanted to use this in a one-liner like with “Get-WmiObject” you can simply do this:

如果您想像“ Get-WmiObject”那樣在單層代碼中使用它,則只需執行以下操作:

?
Get-WmiObject win32_service -ComputerName Server1 -Credential (Get-Credential)

SecureString轉換 (SecureString Conversion)

Ok, now that we covered the interactive scenario, we can get to the fun one. There are two specific commands that are involved when you need to provide a password to your script and want to do it in an automated fashion. The commands do not build the PSCredential object, but help specifically in handling the password in a secure manner:

好的,既然我們已經介紹了交互式場景,那么我們就可以開始有趣了。 當您需要為腳本提供密碼并希望以自動化方式進行操作時,涉及兩個特定命令。 這些命令不會生成PSCredential對象,但是會特別有助于以安全的方式處理密碼:

  • ConvertTo-SecureString

    ConvertTo-SecureString
  • ConvertFrom-SecureString

    ConvertFrom-SecureString

To build this process out you cannot talk about one command with out the other. Even reading the documentation you can see these commands are used in with each other. The first command, ConvertTo, takes a plain text string as input or an encrypted string (via methods shown previously). The output of the command is a SecureString object:

要建立此過程,您不能一概而論。 即使閱讀文檔,您也可以看到這些命令相互配合使用。 第一個命令ConvertTo使用純文本字符串作為輸入或加密的字符串(通過前面顯示的方法)。 該命令的輸出是一個SecureString對象:

?
$pwd = ConvertTo-SecureString "MySuperSecretPassword" -AsPlainText -Force
$pwd.GetType()

Now, when you pipe the output to ConvertFrom, it changes it to an encrypted standard string. This is where a bit of automation can be used. If you output the contents to a text file, it can then be read back and used in the creation of a PSCredential object.

現在,將輸出傳遞給ConvertFrom時,它將其更改為加密的標準字符串。 這是可以使用一些自動化的地方。 如果將內容輸出到文本文件,則可以將其讀回并用于創建PSCredential對象。

?
# build the file with the encrypted password
ConvertTo-SecureString "MySuperSecretPassword" -AsPlainText -Force | ConvertFrom-SecureString | Out-File "C:\SomeSecureLocation\pwd.txt"# read it back in to get the SecureString
$t = Get-Content "C:\SomeSecureLocation\pwd.txt" | ConvertTo-SecureString

While this process would work for a single server, it does not if you need to use this password across multiple servers. Why is that you ask? There is a parameter for both commands, “-Key”, that is not required, but as stated in the help documentation:

盡管此過程適用于單個服務器,但如果您需要在多個服務器上使用此密碼,則無效。 你為什么要問? 這兩個命令都有一個參數“ -Key”,它不是必需的,但如幫助文檔中所述:

Specifies the encryption key to use when converting a secure string into an encrypted standard string. Valid key lengths are 16, 24, and 32 bytes.

指定將安全字符串轉換為加密標準字符串時要使用的加密密鑰。 有效密鑰長度為16、24和32個字節。

If you do not provide a value (Byte[]) for this parameter the command will utilize the DPAPI (Windows Data Protection API) to do the encryption. If you are not familiar with this API it is basically the operating system-level data protection (encryption) on each server. So if you let DPAPI do the encryption, then it goes to reason that only that single machine can decrypt it. If you try to convert the contents of that file on another server you will get an error about an invalid key.

如果沒有為此參數提供值(Byte []),則該命令將利用DPAPI(Windows數據保護API)進行加密。 如果您不熟悉此API,則基本上是每臺服務器上的操作系統級數據保護(加密)。 因此,如果讓DPAPI進行加密,則會導致僅該一臺計算機可以對其進行解密的原因。 如果嘗試在另一個服務器上轉換該文件的內容,則會收到有關無效密鑰的錯誤消息。

So to make this automated and mobile, to use on any server in your environment, we need to utilize the “-Key” parameter. We just need to generate a “Byte[]” key and pass that into the command. You can generate a key with random bytes, and then use that each time you need to read that password into your script.

因此,要使此自動化和移動性能夠在您環境中的任何服務器上使用,我們需要利用“ -Key”參數。 我們只需要生成一個“ Byte []”鍵并將其傳遞給命令即可。 您可以生成具有隨機字節的密鑰,然后在每次需要將該密碼讀入腳本時使用該密鑰。

輔助功能 (Helper Functions)

I often forget the full syntax with commands that I do not have to use often. I don’t remember things I can look up most of the time. However, other ways I use to remember things with PowerShell, is to build functions that remember for me. So I built out three commands to share with you for the above process. I hope you find these useful for those one-time processes like building a secure password file a script being deployed in your environment. The functions contain help information but I will provide a full example that shows how they can be used below.

我經常忘記不需要使用的完整語法。 我不記得我大部分時間都可以查詢的內容。 但是,我用PowerShell記住事情的其他方法是建立對我來說有用的函數。 因此,我為以上過程構建了三個命令與您共享。 我希望您發現這些對一次性過程有用,例如構建安全密碼文件,在環境中部署腳本。 這些功能包含幫助信息,但是我將在下面提供一個完整的示例,說明如何使用它們。

You can download the script here.

您可以在此處下載腳本。

?
# (1) Create our key file
New-KeyFile -KeyFile .\MyKey.key -KeySize 16
# (2) Create our password file
New-PasswordFile -PwdFile .\MyPwd.txt -Key (Get-Content .\MyKey.key)
# (3) Pull in the password to use
$pwd = Get-SecurePassword -PwdFile .\MyPwd.txt -KeyFile .\MyKey.key# build the PSCredential object
$mycred = New-Object System.Management.Automation.PSCredential("MyUserName",$pwd)# show the password was captured
$mycred.GetNetworkCredential().Password

摘要 (Summary)

I hope the above shows that there are methods to help in keeping passwords a bit more secure than plain text. You may have processes or scripts that could already utilize the above code (e.g.?creating Active Directory accounts, etc., and hope this helps.

我希望以上內容表明,有一些方法可以使密碼比純文本安全一些。 您可能已經使用上面的代碼(例如,創建Active Directory帳戶等)的進程或腳本,希望對您有所幫助。

翻譯自: https://www.sqlshack.com/how-to-secure-your-passwords-with-powershell/

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/144168.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息