Fabric认证失败的问题:certificate signed by unknown authority

Fabric认证失败的问题:certificate signed by unknown authority

在调试fabric的时候我们经常会碰到证书认证失败的问题,例如:

Principal deserialization failure (the supplied identity is not valid: x509: certificate signed by unknown authority 
(possibly because of "x509: ECDSA verification failure"
while trying to verify candidate authority certificate "peer0.org0.example.com"))

或者

Error: Failed to deserialize creator identity, err The supplied identity is not valid, 
Verify() returned x509: certificate signed by unknown authority
(possibly because of "x509: ECDSA verification failure" 
while trying to verify candidate authority certificate "peer1.org1.example.com")

等等,这些错误,
然后会打印出identity信息,如下格式:

0a0a53616d654f72674d535012fb062d2d2d2d2d ...... 3d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a

我就想知道到底客户端发来的证书是什么内容,是不是正确的证书,而orderer/peer打印出来的证书内容是identity的序列号后的内容,显然是看不懂的;所以每回我都要进去改orderer或者peer的源代码,在相应位置把identity转换成PEM,然后再把PEM内容打出来,变成一个通用的文本。但是每回改源代码重编译再重新运行是个繁琐的过程。

所以这里开发一个小工具输入identity的序列化后的内容,输出PEM格式文本。这样每次看到日志报错的时候,直接把屏幕打出来的identity的字符序列拷贝出来,用工具一翻译,就输出PEM格式证书,之后就可以用openssl的工具来访问操作PEM证书了。

package main

import (
    "os"
    "fmt"
    "time"
    "bufio"
    "errors"
    "math/big"
    "crypto/x509/pkix"
    "crypto/x509"
    "encoding/hex"
    "encoding/pem"
    "encoding/asn1"
    "github.com/golang/protobuf/proto"
    "github.com/hyperledger/fabric/protos/msp"
)

type validity struct {
    NotBefore, NotAfter time.Time
}

type publicKeyInfo struct {
    Raw       asn1.RawContent
    Algorithm pkix.AlgorithmIdentifier
    PublicKey asn1.BitString
}

type certificate struct {
    Raw                asn1.RawContent
    TBSCertificate     tbsCertificate
    SignatureAlgorithm pkix.AlgorithmIdentifier
    SignatureValue     asn1.BitString
}

type tbsCertificate struct {
    Raw                asn1.RawContent
    Version            int `asn1:"optional,explicit,default:0,tag:0"`
    SerialNumber       *big.Int
    SignatureAlgorithm pkix.AlgorithmIdentifier
    Issuer             asn1.RawValue
    Validity           validity
    Subject            asn1.RawValue
    PublicKey          publicKeyInfo
    UniqueId           asn1.BitString   `asn1:"optional,tag:1"`
    SubjectUniqueId    asn1.BitString   `asn1:"optional,tag:2"`
    Extensions         []pkix.Extension `asn1:"optional,explicit,tag:3"`
}

func (c certificate) String() (string, error) {
    b, err := asn1.Marshal(c)
    if err != nil {
        return "", err
    }
    block := &pem.Block{
        Bytes: b,
        Type:  "CERTIFICATE",
    }
    b = pem.EncodeToMemory(block)
    return string(b), err
}

func certToPEM(x509Cert *x509.Certificate) (string, error) {
    var newCert certificate
    _, err := asn1.Unmarshal(x509Cert.Raw, &newCert)
    if err != nil {
        return "", err
    }
    return newCert.String()
}

func getSerializedIdentityString(input string) (string, error) {
    file, err := os.Open(input)
    if err != nil {
        return "", err
    }
    defer file.Close()

    scanner := bufio.NewScanner(file)
    scanner.Scan()
    serializedIdentityString := scanner.Text()

    if err := scanner.Err(); err != nil {
        return "", err
    }
    return serializedIdentityString, nil
}

func DecodeIdentity(input string, output string) error {
    var err error

    serializedIdentityString, err := getSerializedIdentityString(input)
    if err != nil {
        return err
    }
    serializedIdentityBuffer, err := hex.DecodeString(serializedIdentityString)
    if err != nil {
        return err
    }

    serializedIdentity := &msp.SerializedIdentity{}
    err = proto.Unmarshal(serializedIdentityBuffer, serializedIdentity)
    if err != nil {
        return err
    }

    pemBlock, _ := pem.Decode(serializedIdentity.IdBytes)
    if pemBlock == nil {
        return errors.New("could not decode the PEM structure")
    }
    x509Cert, err := x509.ParseCertificate(pemBlock.Bytes)
    if err != nil {
        return err
    }

    pemString, err := certToPEM(x509Cert)
    if err != nil {
        return err
    }

    fmt.Printf("MSP=%s\n", serializedIdentity.Mspid)
    fmt.Printf("PEM=%s\n", pemString)
    return nil
}

主函数是DecodeIdentity(),需要一个输入参数:

  1. input 是包含identity内容的文本文件,单行
  2. output 参数忽略

运行结果把mspID和PEM证书内容打印到屏幕。
这些代码都在fabric内部存在,我就是把他们考出来组织在一起,使得能够编译成一个可独立运行的小工具。

你可能感兴趣的:(Fabric认证失败的问题:certificate signed by unknown authority)