简体   繁体   English

如何使用 go 标准库加载 DSA PublicKey

[英]How to load DSA PublicKey using go stdlib

I have a PEM encoded DSA public key.我有一个 PEM 编码的 DSA 公钥。 I need this DSA key so I can verify incoming data.我需要这个 DSA 密钥,以便验证传入的数据。 But I have yet to figure out how to load the key using go crypto library (I am not a crypto expert but from what I'm reading online, DSA is not a popular choice anymore).但我还没有弄清楚如何使用 go 加密库加载密钥(我不是加密专家,但从我在网上阅读的内容来看,DSA 不再是流行的选择)。

I can decode the PEM in to its bytes.我可以将 PEM 解码为其字节。 Which, from what I understand, are DER-encoded ASN.1.据我了解,这是 DER 编码的 ASN.1。 How can I put the PEM blocks in to a golang dsa.PublicKey ?如何将 PEM 块放入 golang dsa.PublicKey

Here's a runnable sample: http://play.golang.org/p/8Ma2qwhT31这是一个可运行的示例: http://play.golang.org/p/8Ma2qwhT31

The code:编码:

package main

import "fmt"
import "encoding/pem"
import "encoding/asn1"
import "crypto/dsa"

var signingPubKey = []byte(`-----BEGIN PUBLIC KEY-----
MIICIDANBgkqhkiG9w0BAQEFAAOCAg0AMIICCAKCAgEApSmU3y4DzPhjnpOrdpPs
cIosWJ4zSV8h02b0abLW6nk7cnb5jSwBZKLrryAlF4vs+cF1mtMYjX0QKtEYq2V6
WVDnoXj3BeLYVbhsHuvxYmwXmAkNsSnhMfSCxsck9y6zuNeH0ovzBD90nISIJw+c
VAnUt0dzc7YKjBqThHRAvi8HoGZlzB7Ryb8ePSW+Mfr4jcH3Mio5T0OH3HTavN6Y
zpnohzQo0blwtwEXZOwrNPjQNrSigdPDrtvM32+hLTIJ75Z2NbIRLBjNlwznu7dQ
Asb/AiPTHXihxCRDm+dH70dps5JfT5Zg9LKsPhANk6fNK3e4wdN89ybQsBaswp9h
xzORVD3UiG4LuqP4LMCadjoEazShEiiveeRBgyiFlIldybuPwSq/gUuFveV5Jnqt
txNG6DnJBlIeYhVlA25XDMjxnJ3w6mi/pZyn9ZR9+hFic7Nm1ra7hRUoigfD/lS3
3AsDoRLy0xZqCWGRUbkhlo9VjDxo5znjv870Td1/+fp9QzSaESPfFAUBFcykDXIU
f1nVeKAkmhkEC9/jGF+VpUsuRV3pjjrLMcuI3+IimfWhWK1C56JJakfT3WB6nwY3
A92g4fyVGaWFKfj83tTNL2rzMkfraExPEP+VGesr8b/QMdBlZRR4WEYG3ObD2v/7
jgOS2Ol4gq8/QdNejP5J4wsCAQM=
-----END PUBLIC KEY-----`)

func main() {
    block, _ := pem.Decode(signingPubKey)
    if block == nil {
        fmt.Errorf("expected block to be non-nil", block)
        return
    }

    var pubkey dsa.PublicKey

    _,err := asn1.Unmarshal(block.Bytes, &pubkey)
    if (err != nil ){
        fmt.Errorf("could not unmarshall data: `%s`", err)
    }

    fmt.Printf("public key param P: %d\n", pubkey.Parameters.P)
    fmt.Printf("public key param Q: %d\n", pubkey.Parameters.Q)
    fmt.Printf("public key param G: %d\n", pubkey.Parameters.G)
    fmt.Printf("public key Y: %d\n", pubkey.Y)

    fmt.Printf("done")
}

Which outputs nil for all values, so obviously the Unmarshal call isn't doing what I want (or something is wrong earlier in the pipeline).它为所有值输出 nil ,因此很明显 Unmarshal 调用没有做我想要的(或者管道早期出现问题)。

I know this is an old question, as there has been no answer for this and I couldn't find anything similar, here is my implementation我知道这是一个老问题,因为没有答案,我找不到类似的东西,这是我的实现


pubKeyPath := "./pubKey.pem"
pubKeyBytes, err := ioutil.ReadFile(pubKeyPath)

if err != nil {
   fmt.Println("Something went wrong when reading the file. Failed with", err)
}

pubBlock, _ := pem.Decode(pubKeyBytes)

// This returns a *dsa.PublicKey, but your IDE might complain
// that its not.
pubKey, err := x509.ParsePKIXPublicKey(pubBlock.Bytes)

// So, type assert:
dsaPubKey, ok := pubKey.(*dsa.PublicKey)

if !ok {
   fmt.Println("Failed to type assert")
}

// Verify something with the Public key
type Person struct {
  email  string 
}

// Assuming that a similar instance of the struct was used for signing
person := Person{ email: "hello@world.com" }
personByteArray, _ := json.Marshal(person)

// r and s are what you get after signing. Using it here to verify
fmt.Println(dsa.Verify(dsaPubKey, personByteArray, r, s))

The above implementation reads the contents of the public key everytime the code is run.上述实现在每次运行代码时都会读取公钥的内容。

If you are generating an executable and would like the contents of the public key to be embedded in the binary when you run go build , use the embed package available in go's stdlib如果您正在生成可执行文件并且希望在运行go build时将公钥的内容嵌入到二进制文件中,请使用 go 的 stdlib 中提供的embed package

import _ from "embed"

//go:embed pubKey.pem
var pubKeyBytes []byte  

The above code snippet will load the public key as bytes at compile time.上面的代码片段将在编译时将公钥作为字节加载。 This will enable us to read from the file system only once!这将使我们只能从文件系统中读取一次!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Go - 如何从PublicKey生成SSH PublicKey指纹,PublicKey的类型可能是[rsa dsa ssh-rsa ssh-dss ecdsa]之一 - Go - How to Generate an SSH PublicKey Fingerprint from PublicKey, the PublicKey's type maybe is one of [ rsa dsa ssh-rsa ssh-dss ecdsa ] 如何将 dsa PublicKey 转换为 PEM 文件使用 golang - how to convert dsa PublicKey to PEM Files use golang 在 Go 中使用 stdlib 中未导出的函数/类型 - Using unexported functions/types from stdlib in Go 如何在Go中通过TCP连接发送rsa.PublicKey? - How to send a rsa.PublicKey over a tcp connection in go? 开始-如何从字符串设置RSA公钥模数? - Go - How to Set RSA PublicKey Modulus from String? 如何使用gore加载本地go文件 - How to load local go file by using gore Go & Docker:我可以在使用 stdlib 时运行 go web 服务器,当我使用自定义包时会发生错误 - Go & Docker: I'm able to run a go web server when using stdlib, when I use custom packages errors occur 使用 x509.MarshalPKCS1PublicKey 从 go 生成 RSA 公钥 - Generating RSA public keys from go using x509.MarshalPKCS1PublicKey Golang 中的路由仅使用 stdlib - Routing in Golang using only stdlib Go + VsCode:Git -> 权限被拒绝(公钥) - Go + VsCode: Git -> Permission denied (publickey)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM