7

使用 PowerShell 快速建立安全密碼的幾種方法 (密碼產生器)

 3 years ago
source link: https://blog.miniasp.com/post/2021/06/02/Password-Generators-using-PowerShell
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

最近看到有人在影片中利用 PowerShell 產生亂數密碼,但是為了簡單產生個密碼,都要打長長的命令也不太實用了吧。所以我打算整理幾個密碼產生器的 PS1 函式,並加入到 $PROFILE 設定檔中,如此一來,日後產生密碼就方便多了! 👍

使用自訂字元亂數產生密碼

  • ("!@#$%^&*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray() | sort {Get-Random})[0..8] -join ''
    
  • function New-RandomPassword {
        param(
            [Parameter()]
            [int]$MinimumPasswordLength = 8,
            [Parameter()]
            [int]$MaximumPasswordLength = 12,
            [Parameter()]
            [switch]$ConvertToSecureString
        )
        $length = Get-Random -Minimum $MinimumPasswordLength -Maximum $MaximumPasswordLength
        $password = ("!@#$%^&*0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray() | sort {Get-Random})[0..$length] -join ''
        if ($ConvertToSecureString.IsPresent) {
            ConvertTo-SecureString -String $password -AsPlainText -Force
        } else {
            $password
        }
    }
    
  • 產生長度 8 ~ 12 字元的密碼

    New-RandomPassword
    

    產生長度 8 ~ 12 字元的密碼,並使用 ConvertTo-SecureString 轉成一組安全字串(SecureString)

    New-RandomPassword -MinimumPasswordLength 10 -MaximumPasswordLength 15 -ConvertToSecureString
    
  • 簡單、易用、跨平台,唯一缺點是 亂數強度 比較沒那麼高,但應該大部分的使用情境下應該都沒問題,當成個人密碼已經綽綽有餘。

使用 System.Web.Security.Membership 靜態類別來建立密碼

  • Add-Type -AssemblyName 'System.Web'; [System.Web.Security.Membership]::GeneratePassword(12, 3)
    
  • function GeneratePassword {
        param(
            [Parameter()]
            [int]$MinimumPasswordLength = 8,
            [Parameter()]
            [int]$MaximumPasswordLength = 12,
            [Parameter()]
            [int]$NumberOfAlphaNumericCharacters = 5,
            [Parameter()]
            [switch]$ConvertToSecureString
        )
    
        Add-Type -AssemblyName 'System.Web'
        $length = Get-Random -Minimum $MinimumPasswordLength -Maximum $MaximumPasswordLength
        $password = [System.Web.Security.Membership]::GeneratePassword($length,$NumberOfAlphaNumericCharacters)
        if ($ConvertToSecureString.IsPresent) {
            ConvertTo-SecureString -String $password -AsPlainText -Force
        } else {
            $password
        }
    }
    
  • 產生長度 8 ~ 12 字元的密碼,其所產生密碼中的非英數字元數下限預設為 5 碼 (例如 @、#、!、%、& 等等)。

    GeneratePassword
    

    產生長度 8 ~ 12 字元的密碼,其所產生密碼中的非英數字元數下限為 6 碼 (例如 @、#、!、%、& 等等)。

    GeneratePassword -NumberOfAlphaNumericCharacters 6
    

    產生長度 10 ~ 15 字元的密碼,並使用 ConvertTo-SecureString 轉成一組安全字串(SecureString)

    GeneratePassword -MinimumPasswordLength 10 -MaximumPasswordLength 15 -ConvertToSecureString
    
  • 簡單、易用、亂數強度高,唯一缺點是僅限 Windows 可用,而且不支援PowerShell Core (pwsh.exe) 環境,因為 System.Web 只有 Windows 平台的 .NET Framework 才有。

批次產生多組密碼

  • function New-Password {
        <#
        .SYNOPSIS
            Generate a random password.
        .DESCRIPTION
            Generate a random password.
        .NOTES
            Change log:
                27/11/2017 - faustonascimento - Swapped Get-Random for System.Random.
                                                Swapped Sort-Object for Fisher-Yates shuffle.
                17/03/2017 - Chris Dent - Created.
        #>
    
        [CmdletBinding()]
        [OutputType([String])]
        param (
            # The length of the password which should be created.
            [Parameter(ValueFromPipeline)]
            [ValidateRange(8, 255)]
            [Int32]$Length = 10,
    
            # The character sets the password may contain. A password will contain at least one of each of the characters.
            [String[]]$CharacterSet = ('abcdefghijklmnopqrstuvwxyz',
                                      'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
                                      '0123456789',
                                      '!$%&^.#;'),
    
            # The number of characters to select from each character set.
            [Int32[]]$CharacterSetCount = (@(1) * $CharacterSet.Count),
            [Parameter()]
            [switch]$ConvertToSecureString
        )
    
        begin {
            $bytes = [Byte[]]::new(4)
            $rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
            $rng.GetBytes($bytes)
    
            $seed = [System.BitConverter]::ToInt32($bytes, 0)
            $rnd = [Random]::new($seed)
    
            if ($CharacterSet.Count -ne $CharacterSetCount.Count) {
                throw "The number of items in -CharacterSet needs to match the number of items in -CharacterSetCount"
            }
    
            $allCharacterSets = [String]::Concat($CharacterSet)
        }
    
        process {
            try {
                $requiredCharLength = 0
                foreach ($i in $CharacterSetCount) {
                    $requiredCharLength += $i
                }
    
                if ($requiredCharLength -gt $Length) {
                    throw "The sum of characters specified by CharacterSetCount is higher than the desired password length"
                }
    
                $password = [Char[]]::new($Length)
                $index = 0
    
                for ($i = 0; $i -lt $CharacterSet.Count; $i++) {
                    for ($j = 0; $j -lt $CharacterSetCount[$i]; $j++) {
                        $password[$index++] = $CharacterSet[$i][$rnd.Next($CharacterSet[$i].Length)]
                    }
                }
    
                for ($i = $index; $i -lt $Length; $i++) {
                    $password[$index++] = $allCharacterSets[$rnd.Next($allCharacterSets.Length)]
                }
    
                # Fisher-Yates shuffle
                for ($i = $Length; $i -gt 0; $i--) {
                    $n = $i - 1
                    $m = $rnd.Next($i)
                    $j = $password[$m]
                    $password[$m] = $password[$n]
                    $password[$n] = $j
                }
    
                $password = [String]::new($password)
                if ($ConvertToSecureString.IsPresent) {
                    ConvertTo-SecureString -String $password -AsPlainText -Force
                } else {
                    $password
                }
            } catch {
                Write-Error -ErrorRecord $_
            }
        }
    }
    
  • 產生長度 10 字元的密碼 (預設長度為 10 個字元)

    New-Password
    

    產生長度 12 字元的密碼

    New-Password -Length 12
    

    產生長度 12 個字元的密碼,但指定 2 個小寫字母、3 個大寫字母、5 個數字、2 個特殊符號

    New-Password -Length 12 -CharacterSetCount 2,3,5,2
    

    產生長度 15 字元的密碼,並使用 ConvertTo-SecureString 轉成一組安全字串(SecureString)

    New-Password -Length 15 -ConvertToSecureString
    

    產生 20 組長度 12 個字元的密碼

    @(12) * 20 | New-Password
    
  • 簡單、易用、跨平台、多功能,唯一缺點是不能產生變動長度的密碼


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK