【问题标题】:Encode Private Key getting Error: asn1: structure error: tags don't match编码私钥得到错误:asn1:结构错误:标签不匹配
【发布时间】:2019-08-23 12:23:14
【问题描述】:

当我尝试解析编码私钥时

示例私钥

-----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)

但同样的错误得到。

【问题讨论】:

  • 你能把你的私钥的标题贴出来吗?
  • -----BEGIN OPENSSH 私钥-----
  • 尝试使用来自x/cryptossh.ParseRawPrivateKey
  • 我尝试了 ssh: no key found
  • 在这一点上,我们无能为力。请发布可重现的代码,包括输入。您可以生成一个新的一次性密钥并在您的示例中使用它。那么我们也许可以提供帮助。

标签: go x509 pkcs#11


【解决方案1】:

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

您可以使用例如生成RSA PRIVATE KEY ssh-keygen -t rsa -f key.pem -m pem-m pem 这里很重要)或openssl genrsa -out key.pem,并使用openssl rsa -check -in key.pem 进行测试。

所以只需做一个块类型检查,并使用case子句中的相应函数来解析key。

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

【讨论】:

    【解决方案2】:

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

    示例私钥:

    -----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)
    }
    
    

    【讨论】:

    • 请编辑您的原始问题,不要创建答案。此外,ssh.ParseRawPrivateKey 采用原始 pem 编码字节,您不应调用 pem.Decode
    • 好的,我尝试删除 pem.decode 但它不会给我结果!说找不到钥匙。
    • 我不确定你在做什么,但这有效:play.golang.org/p/VWs_VNzhGcK 并返回 rsa.PrivateKey
    • 我在字符串上粘贴 pem 内容并且我的编辑器添加选项卡时遇到问题。这使得 ssh.ParseRawPrivateKey 失败。我花了一段时间来实现制表
    猜你喜欢
    • 2019-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-15
    相关资源
    最近更新 更多