Tom*_*son 41 ssh digital-signature
我使用 SSH(准确地说是 Linux 上的 OpenSSH 5.5p1)。我有一把钥匙,上面有密码。我将它用于通常登录计算机的东西。
我也可以用它来签署文件吗?
据我了解,SSH 密钥是一个 RSA(或 DSA)密钥,在 SSH 登录过程中,它用于对发送到服务器的消息进行签名。所以在原则上和实践中,它可以用于签署事物——事实上,这是它的唯一目的。
但据我所知,没有办法使用密钥对任意文件进行签名(就像使用 PGP 时那样)。有没有办法做到这一点?
Tom*_*son 28
单独使用 OpenSSH 工具可能无法做到这一点。
但是使用 OpenSSL 工具可以很容易地完成。事实上,至少有两种方法可以做到。在下面的示例中,~/.ssh/id_rsa是您的私钥。
一种方法是使用dgst:
openssl dgst -sign ~/.ssh/id_rsa some-file
Run Code Online (Sandbox Code Playgroud)
另一种是使用pkeyutl:
openssl pkeyutl -sign -inkey ~/.ssh/id_rsa -in some-file
Run Code Online (Sandbox Code Playgroud)
这两者都将二进制签名写入标准输出。DGST需要一个-hex选项将打印文本表示,有关签名的形式的一些细节。pkeyutl采用了-hexdump一个不太有用的选项。两者都将接受 RSA 和 DSA 密钥。我不知道输出的格式是什么。这两个命令产生不同的格式。我的印象是pkeyutl被认为比dgst更现代。
要验证这些签名:
openssl dgst -verify $PUBLIC_KEY_FILE -signature signature-file some-file
Run Code Online (Sandbox Code Playgroud)
和:
openssl pkeyutl -verify -inkey $PUBLIC_KEY_FILE -sigfile signature-file -in some-file
Run Code Online (Sandbox Code Playgroud)
这里的问题是$PUBLIC_KEY_FILE。OpenSSL 无法读取 OpenSSH 的公钥格式,因此您不能只使用id_rsa.pub. 你有几个选择,都不理想。
如果您有 5.6 或更高版本的 OpenSSH,您显然可以这样做:
ssh-keygen -e -f ~/.ssh/id_rsa.pub -m pem
Run Code Online (Sandbox Code Playgroud)
它将公钥以 PEM 格式写入标准输出,OpenSSL 可以读取。
如果您有私钥,并且它是 RSA 密钥,那么您可以从中提取公钥(我假设 PEM 编码的私钥文件包含公钥的副本,因为无法导出公钥来自私钥本身),并使用它:
openssl rsa -in ~/.ssh/id_rsa -pubout
Run Code Online (Sandbox Code Playgroud)
我不知道是否有等效的 DSA。请注意,此方法需要私钥所有者的一些合作,他必须提取公钥并将其发送给潜在的验证者。
最后,您可以使用一个名为 Lars 的人编写的 Python 程序将公钥从 OpenSSH 转换为 OpenSSL 格式。
ste*_*n.z 13
@Tom 的回答帮助我入门,但没有开箱即用。
这些命令将用于:
使用 pkeyutl
# openssl pkeyutl -sign -inkey ~/.ssh/id_sample -in $1 > $1.sig
# ssh-keygen -e -f ~/.ssh/id_sample.pub -m PKCS8 > pub
# openssl pkeyutl -verify -pubin -inkey pub -in $1 -sigfile $1.sig
Signature Verified Successfully
Run Code Online (Sandbox Code Playgroud)
使用 dgst
# openssl dgst -sign ~/.ssh/id_sample $1 > $1.sig
# ssh-keygen -e -f ~/.ssh/id_sample.pub -m PKCS8 > pub
# openssl dgst -verify pub -signature $1.sig $1
Verified OK
Run Code Online (Sandbox Code Playgroud)
pkeyutl 版本只能对小文件进行签名。而 dgst 可以对任意大的文件进行签名,因为它在对结果签名之前需要一个摘要。
jvp*_*nis 11
我偶然发现了这个旧帖子,正在寻找同样的东西。事实证明,ssh-keygen现在 OpenSSH 工具可以直接使用现有的 SSH 密钥生成和验证签名。这已在OpenSSH 8.1 中引入(于 2019-10-09 发布)中。
使用ssh-keygen签名和验证签名:
echo "Hello, World!" | ssh-keygen -Y sign -n file -f id_rsa > content.txt.sig
echo "Hello, World!" | ssh-keygen -Y check-novalidate -n file -f id_rsa.pub -s content.txt.sig
Run Code Online (Sandbox Code Playgroud)
因为我没有找到ssh-keygen手册页特别有用(还),这里概述了一些有用的命令及其对内容进行签名所需的参数。
签约内容:
ssh-keygen
-Y sign # The 'sign' signature operation
-n <namespace> # Signature namespace (e.g. file or email)
-f <file> # Path to the private key to sign the content with
<files> # Paths to one or more files you want to sign (optional, by default reads from stdin)
Run Code Online (Sandbox Code Playgroud)
检查签名内容的签名:
ssh-keygen
-Y check-novalidate # The 'check' signature operation
-n <namespace> # Namespace the signature was generated in
-f <file> # Path to the public key to validate the signature with
-s <file> # Path to the signature file
Run Code Online (Sandbox Code Playgroud)
检查签名并验证签名者是否有权对内容进行签名:
ssh-keygen
-Y verify # The 'verify' signature operation
-n <namespace> # Namespace the signature was generated in
-f <file> # Path to the ALLOWED SIGNERS file
-s <file> # Path to the signature file
-I <principal> # The expected identity principal used to generate the signature
Run Code Online (Sandbox Code Playgroud)
在 ALLOWED SIGNERS 文件中搜索适用于指定签名的任何主体:
ssh-keygen
-Y find-principals # The 'find principals' signature operation
-f <file> # Path to the ALLOWED SIGNERS file
-s <file> # Path to the signature file
Run Code Online (Sandbox Code Playgroud)
显示您的密钥的主体(通常<username>@<hostname>从生成时开始):
ssh-keygen
-l # Print the key's fingerprint
-f <file> # Path to the public key
Run Code Online (Sandbox Code Playgroud)
从证书颁发机构 (CA) SSH 密钥生成用户证书:
ssh-keygen
-I <cert_id> # The certificate identity
-s <file> # Path to the CA's private key
-n <principals> # Identity principals allowed by the generated certificate
<files> # Path to one or more public keys to generate a certificate for
Run Code Online (Sandbox Code Playgroud)
此文件包含允许对内容进行签名的身份列表,因此用于确定签名是否来自授权来源。该格式类似于众所周知的authorized_keys文件,并在手册页的允许签名者部分中有更详细的描述。
<princpal>[,<principal>,..] [cert-authority] [namespaces="<namespace>[,<namespace>,..]"] <public-key>
Run Code Online (Sandbox Code Playgroud)
例子:
user1@server,user2@server ssh-rsa AAAAX1...
*@server cert-authority ssh-rsa AAAAX1...
Run Code Online (Sandbox Code Playgroud)
生成签名并验证它的最简单方法:
# Generate a new SSH key
ssh-keygen -f id_rsa -N ''
# Create the original content to be signed
echo "Trust me, the author!" > content.txt
# Sign the content
cat content.txt | ssh-keygen -Y sign -n file -f id_rsa > content.txt.sig
# Check the signature of the content
cat content.txt | ssh-keygen -Y check-novalidate -f id_rsa.pub -n file -s content.txt.sig
Run Code Online (Sandbox Code Playgroud)
现在尝试检查包含无效内容的签名:
# Pretend the content has been tampered with by a malicious party
echo "Trust ME, the hacker!" > content-tampered.txt
# Check the signature of the content again (which will fail)
cat content-tampered.txt | ssh-keygen -Y check-novalidate -f id_rsa.pub -n file -s content.txt.sig
Run Code Online (Sandbox Code Playgroud)
请注意,签名已使用check-novalidate签名操作进行了验证。novalidate当您要验证签名是否与内容匹配时,这部分听起来有点吓人。但是,当此检查成功时,它会意味着签名与原始内容匹配。您只是没有关于签名者是否被授权对内容进行签名的信息。
当您拥有信任并希望用于签署内容的公钥时,您可以使用 ALLOWED SIGNERS 文件:
# Export your key's principal
ssh-keygen -l -f id_rsa.pub | cut -d ' ' -f3 > identity
# Create an ALLOWED SIGNERS file
echo "$(cat identity) $(cat id_rsa.pub)" > allowed_signers
# Check signature and verify the signer
cat content.txt | ssh-keygen -Y verify -f allowed_signers -I $(cat identity) -n file -s content.txt.sig
Run Code Online (Sandbox Code Playgroud)
正如您在上面的概述中可能已经看到的那样,OpenSSH 现在也能够签署其他 SSH 密钥。这意味着我们可以使用 SSH 密钥来充当证书颁发机构 (CA),这非常酷!
这允许您为签名做的只是在 ALLOWED SIGNERS 文件中指定 CA 的公钥,而所有由 CA 签名的 SSH 密钥都能够对有效内容进行签名:
# Generate a new CA key
ssh-keygen -f ca -C 'SSH Certificate Authority' -N ''
# Replace the ALLOWED SIGNERS file contents with just the CA's public key
echo "$(cat identity) cert-authority $(cat ca.pub)" > allowed_signers
# Sign your public key using the CA, creating a user certificate
ssh-keygen -I $(cat identity) -s ca -n $(cat identity) id_rsa
# Sign the content by specifying the user certificate (which uses the private key)
cat content.txt | ssh-keygen -Y sign -n file -f id_rsa-cert.pub > content.txt.sig
# Validate the signature using the CA's public key
cat content.txt | ssh-keygen -Y verify -f allowed_signers -I $(cat identity) -n file -s content.txt.sig
Run Code Online (Sandbox Code Playgroud)
现在我们有了一个 CA,我们还可以使用自定义的任意主体,因为它们嵌入在证书中
# Sign your public key using the CA, adding a custom principal
ssh-keygen -I $(cat identity) -s ca -n $(cat identity),trusted-authors id_rsa
# Replace the ALLOWED SIGNERS file contents, allowing only signatures generated by keys with the trusted-authors principal
echo "trusted-authors cert-authority $(cat ca.pub)" > allowed_signers
# Sign the content by specifying the user certificate
cat content.txt | ssh-keygen -Y sign -n file -f id_rsa-cert.pub > content.txt.sig
# Validate the signature using the CA's public key and the expected custom principal
cat content.txt | ssh-keygen -Y verify -f allowed_signers -I trusted-authors -n file -s content.txt.sig
Run Code Online (Sandbox Code Playgroud)
如果您按照上面的命令进行操作,您最终会在目录中看到这些文件:
allowed_signers # List of principal(s) and key combinations authorized to sign the content
ca # Private key of the Certificate Authority
ca.pub # Public key of the Certificate Authority
content-tampered.txt # The content that got tampered with
content.txt # The original content
content.txt.sig # A signature of the original content
id_rsa # Our private key - used to generate the signature
id_rsa-cert.pub # Certificate signed by the CA - used to check and verify the signature
id_rsa.pub # Our public key - used to check the signature
identity # Helper file which contains the identity principal of our private key
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!
| 归档时间: |
|
| 查看次数: |
12301 次 |
| 最近记录: |