共用方式為


適用於 Windows 的 OpenSSH 中的金鑰型驗證

Windows 環境中大部分的驗證都是利用使用者名稱-密碼對來完成,這適用於共用通用網域的系統。 當您在不同網域之間工作時,例如在本地和雲端託管系統之間,此類驗證方式會容易受到暴力破解攻擊的影響。

相較之下,Linux 環境通常會使用公開/私鑰組來驅動不需要使用可猜測密碼的驗證。 OpenSSH 包含可協助支援金鑰型驗證的工具,特別是:

  • ssh-keygen for generating secure keys.
  • ssh-agent and ssh-add for securely storing private keys.
  • scp and sftp to securely copy public key files during initial use of a server.

本檔概述如何在 Windows 上使用這些工具,以搭配安全殼層 (SSH) 開始使用金鑰型驗證。 如果您不熟悉 SSH 金鑰管理,我們強烈建議您檢閱 NIST 檔案 IR 7966,該檔案的標題為 使用安全殼層進行互動式和自動化存取管理的安全性

Key pairs

金鑰組指的是特定驗證通訊協定所使用的公開和私密金鑰檔案。

SSH public key authentication uses asymmetric cryptographic algorithms to generate two key files—one private and the other public. 每個私鑰檔案都相當於密碼,而且在所有情況下都應該保持保護。 如果有人取得您的私密金鑰,他們就可以登入您有權存取的任何 SSH 伺服器。 公鑰是放在 SSH 伺服器上的內容,而且可以共用,而不會危害私鑰。

SSH 伺服器和用戶端可以使用金鑰驗證,將提供的使用者名稱的公鑰與私鑰進行比較。 如果無法根據用戶端私密金鑰驗證伺服器端公開金鑰,驗證就會失敗。

在生成金鑰組時輸入通行密語,即可使用金鑰組實作多重要素驗證。 如需詳細資訊,請參閱 使用者金鑰產生。 驗證時會提示使用者輸入通關密語。 將通關密語與私鑰一起使用於 SSH 用戶端上以驗證使用者。

Important

透過金鑰型驗證開啟的遠端會話沒有相關聯的用戶認證。 因此,會話無法以使用者身分進行外部驗證。 此行為是設計使然。

主機金鑰產生

公鑰具有特定的訪問控制清單 (ACL) 需求,在 Windows 上,等同於只允許系統管理員和系統使用者的存取權。 第一次使用 sshd 服務時,會自動產生主機的密鑰組。

Important

您必須先安裝 OpenSSH Server,才能執行本文中的命令。 如需詳細資訊,請參閱 開始使用OpenSSH for Windows

根據預設,您必須手動啟動 sshd。 若要將它設定為在每次重新啟動伺服器時自動啟動,請從伺服器上提升許可權的 PowerShell 提示字元執行下列命令:

# Set the sshd service to be started automatically.
Get-Service -Name sshd | Set-Service -StartupType Automatic

# Start the sshd service.
Start-Service sshd

Because there's no user associated with the sshd service, the host keys are stored under C:\ProgramData\ssh.

使用者金鑰產生

若要使用金鑰型驗證,您必須先為您的用戶端產生公開/私密金鑰組。 您可以使用 ssh-keygen.exe 來產生金鑰檔案,而且您可以指定下列金鑰產生演演算法:

  • 數位簽章演算法 (DSA)
  • Rivest–Shamir–Adleman (RSA)
  • 橢圓曲線數位簽名演算法 (ECDSA)
  • Ed25519

如果您未指定演算法,則會使用 Ed25519。 應使用強式演算法和金鑰長度,例如本範例中的 ECDSA。

若要使用 ECDSA 演算法產生金鑰檔案,請在用戶端的 PowerShell 或命令提示字元視窗中執行下列命令:

ssh-keygen -t ecdsa

命令的輸出看起來應該像下列幾行,不同之處在於 username 會取代為您的使用者名稱:

Generating public/private ecdsa key pair.
Enter file in which to save the key (C:\Users\username/.ssh/id_ecdsa):

At the prompt, you can select Enter to accept the default file path, or you can specify a path or file name for your generated keys.

接下來,系統會提示您使用複雜密碼來加密私鑰檔案。 一般而言,我們不建議使用空的通行密碼,因為通行密碼可以與密鑰檔案一起使用,以提供雙因素驗證。 但在此範例中,您可以將密碼短語留空。

Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in C:\Users\username/.ssh/id_ecdsa.
Your public key has been saved in C:\Users\username/.ssh/id_ecdsa.pub.
The key fingerprint is:
SHA256:OIzc1yE7joL2Bzy8!gS0j8eGK7bYaH1FmF3sDuMeSj8 username@LOCAL-HOSTNAME

The key's randomart image is:
+--[ECDSA 256]--+
|        .        |
|         o       |
|    . + + .      |
|   o B * = .     |
|   o= B S .      |
|   .=B O o       |
|  + =+% o        |
| *oo.O.E         |
|+.o+=o. .        |
+----[SHA256]-----+

現在,您在指定的位置有一個公用/私人 ECDSA 金鑰組。 .pub 檔案是公鑰,沒有擴展名的檔案是私鑰:

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         6/3/2021   2:55 PM            464 id_ecdsa
-a----         6/3/2021   2:55 PM            103 id_ecdsa.pub

私鑰檔案相當於密碼,應該以您保護密碼的方式受到保護。 您可以使用 ssh-agent,在與 Windows 帳戶相關聯的 Windows 安全性內容中安全地儲存私鑰。 若要將 ssh-agent 服務設定為在每次重新啟動電腦時自動啟動,並使用 ssh-add 來儲存私鑰,請在伺服器上提升許可權的 PowerShell 提示字元中執行下列命令:

# By default, the ssh-agent service is disabled. Configure it to start automatically.
# Run the following command as an administrator.
Get-Service ssh-agent | Set-Service -StartupType Automatic

# Start the service.
Start-Service ssh-agent

# The following command should return a status of Running.
Get-Service ssh-agent

# Load your key files into ssh-agent.
ssh-add $env:USERPROFILE\.ssh\id_ecdsa

將金鑰新增至用戶端上的 ssh-agent 服務之後,ssh-agent 服務會自動擷取本機私鑰,並將其傳遞至 SSH 用戶端。

Important

We recommend that you back up your private key to a secure location and then delete it from the local system after you add it to the ssh-agent service. 使用強式演算法時,無法從代理程式擷取私鑰,例如此範例中的 ECDSA。 如果您無法存取私鑰,您必須建立新的金鑰組,並在您與之互動的所有系統上更新公鑰。

部署公鑰

To use the user key that you created previously, you need to place the contents of your public key (\.ssh\id_ecdsa.pub) on the server into a text file. 檔案的名稱和位置取決於用戶帳戶是本機系統管理員群組的成員還是標準用戶帳戶。 以下各章節涵蓋標準和系統管理使用者。

Standard user

You need to place the contents of your public key (\.ssh\id_ecdsa.pub) on the server into a text file called authorized_keys in C:\Users\username\.ssh\. 您可以使用 OpenSSH scp 安全的檔案傳輸公用程式,或使用 PowerShell 將密鑰寫入檔案,來複製公鑰。

您可以使用下列程式代碼將公鑰複製到伺服器。 在最後一行中,以您的用戶名稱取代 username。 一開始,系統會提示您輸入伺服器用戶帳戶的密碼。

# Get the public key file generated previously on your client.
$authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_ecdsa.pub

# Generate the PowerShell command to run remotely that copies the public key file generated previously on your client to the authorized_keys file on your server.
$remotePowershell = "powershell New-Item -Force -ItemType Directory -Path $env:USERPROFILE\.ssh; Add-Content -Force -Path $env:USERPROFILE\.ssh\authorized_keys -Value '$authorizedKey'"

# Connect to your server and run the PowerShell command by using the $remotePowerShell variable.
ssh username@domain1@contoso.com $remotePowershell

Administrative user

You need to place the contents of your public key (\.ssh\id_ecdsa.pub) on the server into a text file called administrators_authorized_keys in C:\ProgramData\ssh\. 您可以使用 OpenSSH scp 安全的檔案傳輸公用程式,或使用 PowerShell 將密鑰寫入檔案,來複製公鑰。 此檔案上的 ACL 必須設定為只允許系統管理員和系統使用者的存取權。

您可以使用下列程式代碼將公鑰複製到伺服器並設定 ACL。 在最後一行中,以您的用戶名稱取代 username。 一開始,系統會提示您輸入伺服器用戶帳戶的密碼。

Note

此範例展示建立 administrators_authorized_keys 檔案的步驟。 此檔案僅適用於系統管理員帳戶。 您必須使用此檔案來取代使用者配置檔中的特定檔案。

# Get the public key file generated previously on your client.
$authorizedKey = Get-Content -Path $env:USERPROFILE\.ssh\id_ecdsa.pub

# Generate the PowerShell command to run remotely that copies the public key file generated previously on your client to the authorized_keys file on your server.
$remotePowershell = "powershell Add-Content -Force -Path $env:ProgramData\ssh\administrators_authorized_keys -Value '''$authorizedKey''';icacls.exe ""$env:ProgramData\ssh\administrators_authorized_keys"" /inheritance:r /grant ""Administrators:F"" /grant ""SYSTEM:F"""

# Connect to your server and run the PowerShell command by using the $remotePowerShell variable.
ssh username@domain1@contoso.com $remotePowershell

針對非英文的作業系統本地化版本,必須修改腳本以據以顯示組名。 若要防止將許可權授與組名時可能發生的錯誤,您可以使用安全性識別碼 (SID) 取代組名。 您可以執行 Get-LocalGroup | Select-Object Name, SID來擷取 SID。 當您使用 SID 取代組名時,其前面必須加上星號(*)。 In the following example, the Administrators group uses the SID S-1-5-32-544:

$remotePowershell = "powershell Add-Content -Force -Path $env:ProgramData\ssh\administrators_authorized_keys -Value '''$authorizedKey''';icacls.exe ""$env:ProgramData\ssh\administrators_authorized_keys"" /inheritance:r /grant ""*S-1-5-32-544:F"" /grant ""SYSTEM:F"""

這些步驟會完成在 Windows 上搭配 OpenSSH 使用金鑰型驗證所需的設定。 執行這些 PowerShell 命令之後,您可以從具有私鑰的任何用戶端連線到 sshd 主機。