Published on

读取secp256k1 pem文件

Authors

知识点

  • pem 证书封装的文件格式
  • x509 证书格式标准 通过头 --- PUBLIC KEY --- ,--- PRIVATE KEY --- ,常见的这种事PKCS8格式
  • ecdsa 数字签名算法,即ECC非对称加密与DAS对称加密这种组合的称呼
  • secp256k1 一种ECC算法,常用于区块链btc,eth。其他ECC一般是用P256算法

主要步骤

  1. 将pem文件格式解码,使用go官方encoding/pem包
  2. 将解码的[]byte数据通过x509库解析,使用crypto/x509库,根据不同的加密算法解析成不同的密钥结构

代码实现

由于go没有官方的x509支持secp256k1的解析,需要使用第三方工具,替换官方的库 PDXbaap/go-std-ext: Golang Standard Library Extends (github.com) 这个库好像只支持到go 1.14.8 再高没测试过,只支持linux环境

package main

import (

	// "encoding/base64"

	"crypto/ecdsa"
	"crypto/x509"
	"encoding/hex"
	"encoding/pem"
	"fmt"
	"io/ioutil"

	"github.com/wumansgy/goEncrypt/ecc"
)

func readPem(pemPath string) []byte {

	b, err := ioutil.ReadFile(pemPath)
	if err != nil {
		fmt.Println(err)
	}

	p, r := pem.Decode(b)
	fmt.Printf("%v\n%v\n%v, r=%v", p.Type, p.Headers, p.Bytes, r)

	return p.Bytes
}

func main() {
	priKey := readPem("key.pem")
	// s := base64.StdEncoding.EncodeToString(b)
	hexs := hex.EncodeToString(priKey)
	fmt.Println("pem=" + hexs)

	tempPrivateKey, err := x509.ParsePKCS8PrivateKey(priKey)
	if err != nil {
		fmt.Printf("x509,%v\n", err)
		return
	}
	ecdsaPri, ok := tempPrivateKey.(*ecdsa.PrivateKey)
	if ok == false {
		fmt.Println("断言失败")
		return
	}

	eccPri := ecc.ImportECDSA(ecdsaPri)
	// eccPri.PublicKey.
	// eccPri.D.Bytes()
	fmt.Println(hex.EncodeToString(eccPri.D.Bytes()))
	fmt.Println(hex.EncodeToString(eccPri.PublicKey.Curve.Params().B.Bytes()))
	fmt.Println(hex.EncodeToString(eccPri.PublicKey.X.Bytes()))
	fmt.Println(hex.EncodeToString(eccPri.PublicKey.Y.Bytes()))

	pubB := readPem("pub.pem")
	fmt.Println(hex.EncodeToString(pubB))
	tempPubKey, err := x509.ParsePKIXPublicKey(pubB)
	if err != nil {
		fmt.Errorf("x509 pubKey %v\n", err)
	}
	ecdsaPub, ok := tempPubKey.(*ecdsa.PublicKey)
	if ok == false {
		fmt.Errorf("断言失败=\n")
		return
	}
	eccPub := ecc.ImportECDSAPublic(ecdsaPub)
	fmt.Println(hex.EncodeToString(eccPub.X.Bytes()))
	fmt.Println(hex.EncodeToString(eccPub.Y.Bytes()))
}

封装pem则反之即可,x509.Marshl