编码私钥获取错误:asn1:结构错误:标记不匹配

时间:2019-04-02 08:36:19

标签: go x509 pkcs#11

当我尝试使用解析私钥时

样本私钥

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEA4if4vmEnNh2Ijlfrhsb02Exh+LXjkYySOiILtj8rg1ZGWFz1vtPe
DiKbbWLo9xcjDp7UQ2gHnhUZno/gFxcokzTYTkexpb/s4mzU4CH0XaS7IV/xRz1Of1+dwC
2MvsclD0NKceyNu0glocGUu6w2MMsWdevr8YqjPABZYwPmANg5wns61FoI5uQi4e6pcNkr
gGnbf1Sh8DChuM22aLksmOW9UapEKovaUxA4DxEd58zJpmg7UN1ZduUrwCVz1tg1BF+EW5
knMd037olDWdgZtEzMxbmSRlqF6t5dcybnp7LQsdPrbXDubY3mjqgCg25xMk4of3mdDc5b
VcRuNSbDmwAAA+AnwUz5J8FM+QAAAAdzc2gtcnNhAAABAQDiJ/i+YSc2HYiOV+uGxvTYTG
H4teORjJI6Igu2PyuDVkZYXPW+094OIpttYuj3FyMOntRDaAeeFRmej+AXFyiTNNhOR7Gl
v+zibNTgIfRdpLshX/FHPU5/X53ALYy+xyUPQ0px7I27SCWhwZS7rDYwyxZ16+vxiqM8AF
ljA+YA2DnCezrUWgjm5CLh7qlw2SuAadt/VKHwMKG4zbZouSyY5b1RqkQqi9pTEDgPER3n
zMmmaDtQ3Vl25SvAJXPW2DUEX4RbmScx3TfuiUNZ2Bm0TMzFuZJGWoXq3l1zJuenstCx0+
ttcO5tjeaOqAKDbnEyTih/eZ0NzltVxG41JsObAAAAAwEAAQAAAQBUyVuONGo49ZWOmBOq
8cg1l11bmwV4OdVQihcN+lzb3mp9EkzngBLOBddziROCH2B7SLyXkNbaQ1rZgWMoBPynQ7
acknBdjbjHormkVdaBjRLDDm8soCVfx38i33DWzV5tfHLahy8TuZayMBsMySF/5YPELfDF
G47bHd5lKr7+LV3T4kvZ1g1UpDgUGlwpVMpu+ybfhMhCOO2w5Vz/Fl7ptYJQnx8rDARgYu
GDf1yKpRCt7Rx4U+lla5HMnoxh4/g5dXDb8vBDfC/QXj+DPY2/Ju5c3zifryfkB2Cvppq2
EULxDO41iwXgzRpmv9hv6adSp2Qqob72XDu7mWdz/u9BAAAAgFDu2TKaU71igLIMd4sheb
wzjsB2ZW8x5CO+N95OKddkC6lkJiBFrAiF98SVs0AFbqDlw46V3xrBqCVL6ByfW4Zro3Qw
C9GRhjfW/koyuJbplf0uiNaa1ApM7nRoRiOcE5kXkLOObxojPuur29rbI1JGozSn6YhxwA
Q3WthgQipmAAAAgQD7RXYeHQ1P0gpdpWfMXspIbkzODWQDH3VkvQHFFl87+QpsFIWGd8zX
jMMo2bELCgr9cnzRffd8UUCzWJy/mfj+PWjsCr9EaojlnDWYEComa5PYkJKKOxmN+rLg7P
F3Xd/KV4XVBP5wqobTU1sxLnhJkVJMCqHOdDzv9mYr75sXqwAAAIEA5mmDj/4mvkNTNZKw
aaD/8sOz7JjD90jqQCchLETVcwJ1sCgPl5qVAa/S99g9QJXuW3TlXbj4jw01s5APpKq6eY
H91+vJcS8ZmzARXMt4jVB3oWsrhFXw5BEaKYjyKx5gYdSGETbcGz1WxQF4i5E/A43ow73n
RftprflPg+CUU9EAAAAkc3VtaXR0aGFrdXJAU3VtaXRzLU1hY0Jvb2stQWlyLmxvY2FsAQ
IDBAUGBw==
-----END OPENSSH PRIVATE KEY-----
 x509.ParsePKCS1PrivateKey(block.Bytes)

这会给我错误 说明:

case "OPENSSH PRIVATE KEY":
        log.Println("Here at OPENSSH Private Key:")
        rsa, err := x509.ParsePKCS1PrivateKey(block.Bytes)
        log.Println("Rsa and Error:", rsa, err)
        if err != nil {
            return nil, err
        }
        rawkey = rsa

-----BEGIN OPENSSH PRIVATE KEY-----
key
-----END OPENSSH PRIVATE KEY-----

获取错误:

asn1: structure error: tags don't match (16 vs {class:1 tag:15 length:112 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} pkcs1PrivateKey @2
2019/04/02 13:57:52 Signer: <nil>

我也将尝试

 x509.ParsePKCS8PrivateKey(block.Bytes)

但是得到同样的错误。

2 个答案:

答案 0 :(得分:1)

问题是密钥类型。 OPENSSH PRIVATE KEY应该用ssh.ParseRawPrivateKey来解析,而RSA PRIVATE KEY可以同时用ssh.ParseRawPrivateKeyx509.ParsePKCS1PrivateKey来解析。

您可以使用以下方式生成RSA PRIVATE KEYssh-keygen -t rsa -f key.pem -m pem(此处很重要 -m pem )或openssl genrsa -out key.pem,然后用openssl rsa -check -in key.pem对其进行测试。

所以只需执行块类型检查,并在case子句中使用相应的函数来解析密钥。

还要考虑密钥加密,这意味着您可能还需要使用ssh.ParseRawPrivateKeyWithPassphrasex509.IsEncryptedPEMBlockx509.DecryptPEMBlock函数。

答案 1 :(得分:0)

我发布了测试私钥和我使用的代码

示例私钥:

-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEA4if4vmEnNh2Ijlfrhsb02Exh+LXjkYySOiILtj8rg1ZGWFz1vtPe
DiKbbWLo9xcjDp7UQ2gHnhUZno/gFxcokzTYTkexpb/s4mzU4CH0XaS7IV/xRz1Of1+dwC
2MvsclD0NKceyNu0glocGUu6w2MMsWdevr8YqjPABZYwPmANg5wns61FoI5uQi4e6pcNkr
gGnbf1Sh8DChuM22aLksmOW9UapEKovaUxA4DxEd58zJpmg7UN1ZduUrwCVz1tg1BF+EW5
knMd037olDWdgZtEzMxbmSRlqF6t5dcybnp7LQsdPrbXDubY3mjqgCg25xMk4of3mdDc5b
VcRuNSbDmwAAA+AnwUz5J8FM+QAAAAdzc2gtcnNhAAABAQDiJ/i+YSc2HYiOV+uGxvTYTG
H4teORjJI6Igu2PyuDVkZYXPW+094OIpttYuj3FyMOntRDaAeeFRmej+AXFyiTNNhOR7Gl
v+zibNTgIfRdpLshX/FHPU5/X53ALYy+xyUPQ0px7I27SCWhwZS7rDYwyxZ16+vxiqM8AF
ljA+YA2DnCezrUWgjm5CLh7qlw2SuAadt/VKHwMKG4zbZouSyY5b1RqkQqi9pTEDgPER3n
zMmmaDtQ3Vl25SvAJXPW2DUEX4RbmScx3TfuiUNZ2Bm0TMzFuZJGWoXq3l1zJuenstCx0+
ttcO5tjeaOqAKDbnEyTih/eZ0NzltVxG41JsObAAAAAwEAAQAAAQBUyVuONGo49ZWOmBOq
8cg1l11bmwV4OdVQihcN+lzb3mp9EkzngBLOBddziROCH2B7SLyXkNbaQ1rZgWMoBPynQ7
acknBdjbjHormkVdaBjRLDDm8soCVfx38i33DWzV5tfHLahy8TuZayMBsMySF/5YPELfDF
G47bHd5lKr7+LV3T4kvZ1g1UpDgUGlwpVMpu+ybfhMhCOO2w5Vz/Fl7ptYJQnx8rDARgYu
GDf1yKpRCt7Rx4U+lla5HMnoxh4/g5dXDb8vBDfC/QXj+DPY2/Ju5c3zifryfkB2Cvppq2
EULxDO41iwXgzRpmv9hv6adSp2Qqob72XDu7mWdz/u9BAAAAgFDu2TKaU71igLIMd4sheb
wzjsB2ZW8x5CO+N95OKddkC6lkJiBFrAiF98SVs0AFbqDlw46V3xrBqCVL6ByfW4Zro3Qw
C9GRhjfW/koyuJbplf0uiNaa1ApM7nRoRiOcE5kXkLOObxojPuur29rbI1JGozSn6YhxwA
Q3WthgQipmAAAAgQD7RXYeHQ1P0gpdpWfMXspIbkzODWQDH3VkvQHFFl87+QpsFIWGd8zX
jMMo2bELCgr9cnzRffd8UUCzWJy/mfj+PWjsCr9EaojlnDWYEComa5PYkJKKOxmN+rLg7P
F3Xd/KV4XVBP5wqobTU1sxLnhJkVJMCqHOdDzv9mYr75sXqwAAAIEA5mmDj/4mvkNTNZKw
aaD/8sOz7JjD90jqQCchLETVcwJ1sCgPl5qVAa/S99g9QJXuW3TlXbj4jw01s5APpKq6eY
H91+vJcS8ZmzARXMt4jVB3oWsrhFXw5BEaKYjyKx5gYdSGETbcGz1WxQF4i5E/A43ow73n
RftprflPg+CUU9EAAAAkc3VtaXR0aGFrdXJAU3VtaXRzLU1hY0Jvb2stQWlyLmxvY2FsAQ
IDBAUGBw==
-----END OPENSSH PRIVATE KEY-----

用业务私钥对构造的json字符串签名

func SignatureWithPrivateKey(data string) string {
    signer, err := loadPrivateKey("/Users/sumitthakur/test")
    log.Println("Signer:", signer)
    if err != nil {
        fmt.Errorf("signer is damaged: %v", err)
    }

    toSign := data

    signed, err := signer.Sign([]byte(toSign))
    if err != nil {
        fmt.Errorf("could not sign request: %v", err)
    }
    return base64.StdEncoding.EncodeToString(signed)

}

loadPrivateKey加载解析为PEM编码的私钥文件。

func loadPrivateKey(path string) (Signer, error) {
    data, err := ioutil.ReadFile(path)
    if err != nil {
        return nil, err
    }
    log.Println("Data and Error pem:", data, err)
    return parsePrivateKey(data)
}

解析已编码的私钥。

func parsePrivateKey(pemBytes []byte) (Signer, error) {
    block, err := pem.Decode(pemBytes)
    if block == nil {
        return nil, errors.New("ssh: no key found")
    }

    log.Println("Block and Error: ", block, err)

    var rawkey interface{}
    switch block.Type {
    case "OPENSSH PRIVATE KEY":
        log.Println("Here at OPENSSH Private Key:")
        rsa, err := ssh.ParseRawPrivateKey(block.Bytes)
        log.Println("Rsa and Error:", rsa, err)
        if err != nil {
            return nil, err
        }
        rawkey = rsa
    default:
        log.Println("Here at default")
        return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
    }
    return newSignerFromKey(rawkey)
}