将rsa.PublicKey转换为ssh.PublicKey

时间:2016-07-26 02:02:03

标签: go cryptography rsa ssh-keys

我有一个rsa.PublicKey,它由一个模数和一个结构中的公共exponenet组成。我想验证使用该密钥签名的ssh.Signature,我想如果我有ssh.PublicKey我可以在该接口上调用Verify方法。但是,我找不到任何实现ssh.PublicKey并支持从rsa.PublicKey转换的类。我是否需要编写专有方法来执行此操作,或者是否有一些我找不到的课程,或者更好的方法来解决我的问题?

对于上下文,我从rsa.PublicKey获得了x509.Certificate来自yubikey,证明了其中一个PIV插槽中的密钥。

1 个答案:

答案 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