1 回答
TA贡献1789条经验 获得超10个赞
那是一个SSH证书文件,用于实现基于SSH证书的用户认证。这通过检查公钥层次结构中受信任的证书颁发机构的有效签名来验证用户登录的真实性。与标准的基于 SSH 密钥的身份验证(使用文件)相比,这种方法具有多种优势authorized_keys
,例如:
控制密钥文件的发布(有权访问 CA 主密钥的人必须签署新证书,而不是用户发布自己的证书
ssh-keygen
)自动密钥文件到期
添加或轮换证书时减少管理开销,因为只需要 CA 的公钥来验证证书;不再需要
authorized_keys
为每个主机上的每个用户填充一个文件当与用户的关系发生变化时,为证书吊销提供更简单的支持
假设您使用的是内置golang.org/x/crypto/ssh
库,您可以通过以下方式实现:
读入并解析您签名的公钥证书和私钥
从私钥创建签名者
使用读入的公钥和相应的私钥签名者创建证书签名者
OpenSSH 公钥证书的指定格式类似于文件authorized_keys
。ParseAuthorizedKeys
Go库的函数会解析这个文件,将对应的key作为接口实例返回ssh.PublicKey
;对于证书,这具体是结构的一个实例ssh.Certificate
。
请参阅代码示例(注意:我HostKeyCallback
在您的代码中添加了一个ClientConfig
以实现与测试盒的连接——但是,它使用了InsecureIgnoreHostKey
检查器,我不建议在生产中使用它!)。
package main
import (
"bytes"
"io/ioutil"
"log"
"golang.org/x/crypto/ssh"
)
func main() {
key, err := ioutil.ReadFile("/tmp/mycert")
if err != nil {
log.Fatalf("unable to read private key: %v", err)
}
// Create the Signer for this private key.
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
log.Fatalf("unable to parse private key: %v", err)
}
// Load the certificate
cert, err := ioutil.ReadFile("/tmp/mycert-cert.pub")
if err != nil {
log.Fatalf("unable to read certificate file: %v", err)
}
pk, _, _, _, err := ssh.ParseAuthorizedKey(cert)
if err != nil {
log.Fatalf("unable to parse public key: %v", err)
}
certSigner, err := ssh.NewCertSigner(pk.(*ssh.Certificate), signer)
if err != nil {
log.Fatalf("failed to create cert signer: %v", err)
}
config := &ssh.ClientConfig{
User: "user",
Auth: []ssh.AuthMethod{
// Use the PublicKeys method for remote authentication.
ssh.PublicKeys(certSigner),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
// Connect to the remote server and perform the SSH handshake.
client, err := ssh.Dial("tcp", "host.com:22", config)
if err != nil {
log.Fatalf("unable to connect: %v", err)
}
defer client.Close()
}
如果您想编写一个更通用的支持证书和非证书的连接客户端,您显然需要额外的逻辑来处理其他类型的公钥。如所写,我希望pk.(*ssh.Certificate)非证书公钥文件的类型断言失败!(实际上,对于非证书连接,您可能根本不需要读取公钥。)
- 1 回答
- 0 关注
- 145 浏览
添加回答
举报