GmSSL Go API
GmSSL-Go [https://github.com/guanzhi/GmSSL/tree/master/go] 是GmSSL库的Go语言接口绑定,为Go语言应用提供密码算法、X.509证书、SSL协议和Engine等功能。GmSSL-Go以CGO方式将GmSSL的高层接口封装为Go语言组件,是一个与GmSSL库松耦合的轻量级的中间层,所有的密码功能均由底层的GmSSL库提供。
为何用GmSSL-Go
虽然Go语言的官方库提供了常用的密码算法包和SSL协议包,也存在一些第三方的纯Go语言的密码库,在项目中集成GmSSL-Go仍然有很多不可替代的优势:
- GmSSL-Go通过底层的GmSSL库提供完整、丰富的国密算法、证书和SSL协议的支持。
- GmSSL-Go可以通过Engine对象满足国密标准的U盾、PCI-E加密卡等国产硬件密码设备,提供系统的安全性、可用性和密码合规性。
- GmSSL-Go以CGO方式调用GmSSL库的密码算法实现,相对于纯Go语言实现在密码算法上具有性能上的优势,请参考GmSSL Benchmark。
- GmSSL-Go的功能和性能随着GmSSL的升级获得持续的改进。
GmSSL-Go的编译与安装
GmSSL-Go的编译和运行依赖GmSSL的C库,即libcrypto
、libssl
和头文件,在编译安装GmSSL-Go之前应确保GmSSL的C库已经编译安装完成,GmSSL的C库编译安装请参考文档中的编译和安装一节。
GmSSL-Go是一个CGO项目,在编译前应将代码复制到GOPATH
目录下的源代码目录。通常系统中的默认GOPATH
目录为/home/<username>/go
,GmSSL-Go代码的go/gmssl
和go/gmssltest
分别复制到/home/<username>/go/src/gmssl
和/home/<username>/go/src/gmssltest
,在这两个目录中可以运行go build
、go install
来编译和安装,或者在gmssltest
目录下运行go run gmssltest.go
来测试。
GmSSL-Go接口概述
GmSSL-Go的核心接口是用CGO实现的gmssl
包,后续可能会在这组接口的基础上再封装一层兼容Go官方库的中间层。
由于GmSSL-Go的密码功能都是由底层的GmSSL库提供的,不同的编译选项可能导致底层的GmSSL库支持的密码算法不尽相同,因此应用在调用GmSSL-Go的时候可以首先检查GmSSL-Go接口的版本、GmSSL库的版本,以及GmSSL库支持的算法列表。其中函数GetVersions
返回GmSSL-Go和GmSSL库的版本号,GetDigestNames
、GetCipherNames
、GetPublicKeyAlgorithmNames
、GetSignAlgorithmNames
、GetPublicKeyEncryptionNames
、GetDeriveKeyAlgorithmNames
返回当前GmSSL库支持的各类算法列表,需要注意的是,一些较新的算法,如SHA-3,或者已经不安全的算法,如DES
、MD5
等,可能不包含在GmSSL库的默认配置中,在调用这些算法前可以通过上述接口进行检查。
GmSSL-Go的密码功能及服务接口如下:
- 通过
GenerateRandom
函数生成随机数,在生成对称密钥、IV时应优先使用该函数。在缺乏随机性的嵌入式环境中,可以通过SeedRandom
函数为随机数生成器提供格外的熵。 - 通过
DigestContext
、CipherContext
、HMACContext
对象提供哈希、对称加密和HMAC,这些对象通过Update/Final
接口提供增量的数据处理能力。 - 通过
PrivateKey
、PublicKey
对象提供公私钥生成以及签名验证、公钥加解密、密钥交换等功能,需要注意的是,这组接口是GmSSL中EVP_PKEY_xxx
系列接口的CGO封装,不支持组合式的密码功能,这意味着签名函数的输入必须为消息的哈希值而不能是消息本身,公钥加密的输入通常为较短的对称密钥或口令,而不应该是较长的明文消息。由于SM2标准中的数字签名和密钥交换需要一个特殊的哈希值Z,PrivateKey/PublicKey
对象通过ComputeSM2IDDigest
函数提供Z值的生成。 - 通过
Engine
对象提供访问SKF、SDF等密码硬件设备的能力,应用可以调用密码硬件并用硬件设备中的公私钥完成签名、解密等密码功能。 - 通过
Certificate
对象提供X.509数字证书功能,目前该组接口仅支持证书的解析和验证,不支持证书签发等CA所需的功能。 - 通过
SSLContext
和SSLConnections
对象提供SSL客户端功能,不支持服务端功能。
缺失的功能
虽然一些缺失的功能会陆续补充,但是GmSSL-Go并不会试图提供完整的GmSSL功能接口。目前GmSSL-Go预想的典型应用场景为客户端,因此没有提供CA、SSL服务器所需的功能,在这些场景中使用GmSSL-CA、GmSSL反向代理或配置GmSSL的Web Server更为合理。