说明
目前
golang crypto/x509
这个库针对ECC
的密钥只支持P224 / P256 / P384 / P521
这四条曲线,
区块链开发通常使用secp256k1
曲线,当我们想要为secp256k1
密钥签发证书时可以选择在go
中引用libssl.so
也可以选择直接调用openssl
命令,本例提供了更为优雅的第三种选择,使用PDXBaap/go-std-ext
(PDX
官方提供的golang
标准库扩展)
实现让x509
库直使用ECC secp256k1
密钥生成和验证证书;
安装 PDXBaap/go-std-ext
假设本地已经安装了 go1.14.4
以上版本的开发环境
$> go get -v -u github.com/PDXbaap/go-std-ext
...
$> go-std-ext
GOROOT : /usr/local/go/src
VERSION : go version go1.14.4 darwin/amd64
Success.
使用
通过以上步骤安装 go-std-ext
成功以后,可以直接使用标准库生成 ECC secp256k1
密钥
// 生成 ecc secp256k1 密钥
caPrivkey, _ := ecdsa.GenerateKey(elliptic.S256(), rand.Reader)
其中 elliptic.S256()
对应的即为 secp256k1
曲率,这个 ECC
密钥可以直接拿来创建 x509
证书
userPrv, _ := ecdsa.GenerateKey(elliptic.S256(), rand.Reader)
certTemplate := &x509.Certificate{ ... }
...
// 为 ecc secp256k1 公钥签发 x509 数字证书
certBuf, err := x509.CreateCertificate(rand.Reader, certTemplate, caCert, userPrv.Public(), caPrivkey)
...
测试
样例代码都可以在 s256k1_cert.go
中获得 , 并可以通过 s256k1_cert_test.go
进行测试,其中包含了密钥和证书的生成与验证;
生成 S256
密钥证书
执行 s256k1_cert_test.go
中的 TestAll
方法会得到如下结果:
测试代码:https://github.com/cc14514/go-s256k1-cert
=== RUN TestAll
==================================================================== ca key
-----BEGIN ECC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,fd9b8bfdd18b1987f9ca9eff2d3c728e
qWIVrcrxadTVZhOd+a9xEBtVMxdlZMRAI9M1aM9LDjMqZvgrnhNoOrbiZ6Cm7qeN
Ae+AISGkv3/w5AXWqY1I/KFr5m+FRq8Yuf/KMMI6K7IQKHuEt2NF5quhl2grbUze
Ts+//mxG6ScL/MQdLyIZQIAUIz1AXmFVzOU7HEa3lcU=
-----END ECC PRIVATE KEY-----
-----BEGIN ECC PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE8MysP6rQzmiE7iDNanSAu1qcwFlyqCtf
2Cd8uXZh0Pv6d6Yq8naGIXWGdoGKCGVOC1GBCTybUVuvIPYzldu0iw==
-----END ECC PUBLIC KEY-----
==================================================================== ca cert
-----BEGIN CERTIFICATE-----
MIIB0jCCAXegAwIBAgIQfxrDA5/tS1WT0YdFPZf4PjAKBggqhkjOPQQDAjBKMQ8w
DQYDVQQGDAbkuK3lm70xDzANBgNVBAoMBue7hOe7hzEVMBMGA1UECwwM57uE57uH
5Y2V5L2NMQ8wDQYDVQQDDAbkvaDlpb0wHhcNMjAwNzE4MDIwNzAwWhcNMzAwNzE2
MDIwNzAwWjBKMQ8wDQYDVQQGDAbkuK3lm70xDzANBgNVBAoMBue7hOe7hzEVMBMG
A1UECwwM57uE57uH5Y2V5L2NMQ8wDQYDVQQDDAbkvaDlpb0wVjAQBgcqhkjOPQIB
BgUrgQQACgNCAATwzKw/qtDOaITuIM1qdIC7WpzAWXKoK1/YJ3y5dmHQ+/p3piry
doYhdYZ2gYoIZU4LUYEJPJtRW68g9jOV27SLo0IwQDAOBgNVHQ8BAf8EBAMCAZYw
DwYDVR0TAQH/BAUwAwEB/zAdBgNVHREEFjAUgRJjYzE0NTE0QGljbG91ZC5jb20w
CgYIKoZIzj0EAwIDSQAwRgIhAJvADh56SOTCDojMrBS5cvycOueB8K4utKr5VOzv
+ZK0AiEAtOLYwA4WK1Z+jtTv8OKyvKKFfzzgl2dgJFQjwCQISOs=
-----END CERTIFICATE-----
==================================================================== user key
-----BEGIN ECC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,2b81dce585d3ec652266ec9c044f57f3
2MXeBnwBSJYxxEc4apQK4xqtwkNnOmYejthDF9pN6xu7UlI3wg9NpJ8XJ8bvyqoi
8EMpxGS1+VxKSmHUkRN1/nLLQMC6JaszrzlOwgp3Xf437704kV+14WrqZokkqpir
qAC5uzwZMIHJaSnxtHxlj6OwLPiN/ZIG6SnYvdtH7vo=
-----END ECC PRIVATE KEY-----
-----BEGIN ECC PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE0+1Io0gPE4NQAwr9dYXsqGkNEVxXrl6w
6qR3Mc6Fa7TDvrOF/KXfIVMpJSXUBxML1fb50jwbXECR7n2mdTJGXg==
-----END ECC PUBLIC KEY-----
==================================================================== user cert
-----BEGIN CERTIFICATE-----
MIIBtDCCAVugAwIBAgIQE82sZtWDSnudhgqZ0sQtejAKBggqhkjOPQQDAjBKMQ8w
DQYDVQQGDAbkuK3lm70xDzANBgNVBAoMBue7hOe7hzEVMBMGA1UECwwM57uE57uH
5Y2V5L2NMQ8wDQYDVQQDDAbkvaDlpb0wHhcNMjAwNzE4MDIwNzAwWhcNMzAwNzE2
MDIwNzAwWjBHMQ8wDQYDVQQGDAbkuK3lm70xEjAQBgNVBAoMCeeyvuatpumXqDEP
MA0GA1UECwwG5rGf5rmWMQ8wDQYDVQQDDAbpmYjnnJ8wVjAQBgcqhkjOPQIBBgUr
gQQACgNCAATT7UijSA8Tg1ADCv11heyoaQ0RXFeuXrDqpHcxzoVrtMO+s4X8pd8h
UyklJdQHEwvV9vnSPBtcQJHufaZ1MkZeoykwJzAOBgNVHQ8BAf8EBAMCBLAwFQYD
VR0RBA4wDIEKY3pAandtLmNvbTAKBggqhkjOPQQDAgNHADBEAiAbaHQIm5mx8WAJ
qFhNZ8A9Vps7+096WyCZUVixReGntwIgGF7jGblcRy+22x70uKseZf0itsJQG4lP
ZV9t49tovGw=
-----END CERTIFICATE-----
--- PASS: TestAll (0.02s)
并会在 /tmp
目录下生成 ca.pem
和 user.pem
使用 openssl 验证证书
使用 openssl 来验证 go-std-ext 生成的 secp256k1 证书
$>openssl verify -CAfile /tmp/ca.pem /tmp/user.pem
user.pem: OK
验证通过,大功告成。
结束语
对于
crypto
的扩展将从go1.14.4
开始迭代,PDXBaap/go-std-ext
会在每次golang
发布新版本时一同更新,如果您无法安装请及时更新本地的golang
开发环境,截止发稿时间已经对go1.14.4
和go1.14.5
进行了支持;特别注意:安装时
${GOROOT}/src
目录将会被改写,权限根据用户和组进行判断,所以最好将此目录所有权修改为当前用户,例如
chown -R {CURRENT_USER}:{CURRENT_GROUP} {GOROOT}/src