我有一个rsa.PublicKey
,它由一个模数和一个结构中的公共exponenet组成。我想验证使用该密钥签名的ssh.Signature
,我想如果我有ssh.PublicKey
我可以在该接口上调用Verify
方法。但是,我找不到任何实现ssh.PublicKey
并支持从rsa.PublicKey
转换的类。我是否需要编写专有方法来执行此操作,或者是否有一些我找不到的课程,或者更好的方法来解决我的问题?
对于上下文,我从rsa.PublicKey
获得了x509.Certificate
来自yubikey,证明了其中一个PIV插槽中的密钥。
答案 0 :(得分:2)
crypto / ssh包http://godoc.org/golang.org/x/crypto/ssh#NewPublicKey中的NewPublicKey
函数可以使用*rsa.PublicKey
作为参数,并返回包含PublicKey
的{{1}}接口的实例方法(Verify
) - http://godoc.org/golang.org/x/crypto/ssh#PublicKey。
下面的程序说明了这一点 - 我们创建了一个新的* rsa.PrivateKey并使用它签名消息,然后使用Verify(data []byte, sig *Signature) error
函数将*rsa.PublicKey
转换为ssh.PublicKey
并验证签名;如果原始数据被修改,还要检查签名验证是否失败。为简洁起见,省略了错误检查。
package main import ( "crypto/rand" "crypto/rsa" "fmt" "log" "golang.org/x/crypto/ssh" ) func main() { data := []byte("Hello, world!") // create a new key as *rsa.PrivateKey priv, _ := rsa.GenerateKey(rand.Reader, 512) signer, _ := ssh.NewSignerFromKey(priv) sig, _ := signer.Sign(rand.Reader, data) // extract the ssh.PublicKey from *rsa.PublicKey to verify the signature pub, _ := ssh.NewPublicKey(&priv.PublicKey) if err := pub.Verify(data, sig); err != nil { log.Fatalf("publicKey.Verify failed: %v", err) } fmt.Printf("Signature OK\n") // modify the data and make sure we get a failure data[0]++ if err := pub.Verify(data, sig); err == nil { log.Printf("publicKey.Verify passed on bad data/signature, expect failure") } }
输出:
Signature OK