代码地址:https://github.com/Freezingsmile/fabric-gmsm
主要是根据原bccsp的sw文件夹,通过参考里面的rsa、ecdsa、aes等算法的使用,新增sm2、sm3、sm4等算法的调用。
bccsp的代码实现结构
bccsp.go: 主要接口声明的文件,比如 BCCSP、Key、各种 Opts 等, 其中
BCCSP 接口为主要接口。
sw: bccsp 的纯软件实现,内部实现通过调用 go 原生支持的密码算法,并且
提供了一个 keystore 来保存密钥。
pkcs11: bccsp 的 pkcs11 实现,通过调用 pkcs11 接口来实现相关的密码操
作,仅支持 ecdsa、rsa 以及 aes 算法。密钥保存在 pkcs11 通过 pin 口令保
护的数据库或者硬件设备中。
utils:工具包,密钥编码转换等
signer: 实现了 go 的 crypto.signer 接口
factory:factory 是 bccsp 的一个工厂,可以通过这个工厂返回一个具体的
bccsp 实例,比如上面说的 sw 或者 pkcs11,如果添加了自己的 bccsp 实现,
也要讲该 bccsp 添加到 factory 中。
fileks.go:与密钥存储和读取相关
impl.go:sw 的主文件,通过调用 6 中的函数来实现 bccsp 的各个接口。
以算法名字开头的:密码算法实现相关。
以算法名字+key 开头的: 定义该算法密钥的具体数据结构,并实现 Key 接口
以 bccsp 接口函数名开头的:包含了 bccsp 接口各个函数的具体实现代码。
BCCSP 实例是通过工厂来提供的,sw 包对应的工厂在 swFactory.go 中实现,
pkcs11 包对应的工厂在 pkcs11Factory.go 中实现,它们都共同实现了的
BCCSPFactory 接口。
以下主要讲述具有国密算法改动的部分。
sm2.go文件里面调用了SM2类型的签名者和校验者的接口实现。主要包含了签名和验签功能。
func signGMSM2(k *sm2.PrivateKey, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
signature, err = k.Sign(rand.Reader, digest, opts)
return
}
func verifyGMSM2(k *sm2.PublicKey, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
valid = k.Verify(digest, signature)
return
}
type gmsm2Signer struct{}
func (s *gmsm2Signer) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
return signGMSM2(k.(*gmsm2PrivateKey).privKey, digest, opts)
}
type ecdsaPrivateKeySigner struct{}
func (s *ecdsaPrivateKeySigner) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
puk := k.(*ecdsaPrivateKey).privKey.PublicKey
sm2pk := sm2.PublicKey{
Curve: puk.Curve,
X: puk.X,
Y: puk.Y,
}
privKey := k.(*ecdsaPrivateKey).privKey
sm2privKey := sm2.PrivateKey{
D: privKey.D,
PublicKey: sm2pk,
}
return signGMSM2(&sm2privKey, digest, opts)
}
type gmsm2PrivateKeyVerifier struct{}
func (v *gmsm2PrivateKeyVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
return verifyGMSM2(&(k.(*gmsm2PrivateKey).privKey.PublicKey), signature, digest, opts)
}
type gmsm2PublicKeyKeyVerifier struct{}
func (v *gmsm2PublicKeyKeyVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
return verifyGMSM2(k.(*gmsm2PublicKey).pubKey, signature, digest, opts)
}
type ecdsaPrivateKeyVerifier struct{}
func (v *ecdsaPrivateKeyVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
puk := k.(*ecdsaPrivateKey).privKey.PublicKey
sm2pk := sm2.PublicKey{
Curve: puk.Curve,
X: puk.X,
Y: puk.Y,
}
return verifyGMSM2(&sm2pk, signature, digest, opts)
}
type ecdsaPublicKeyKeyVerifier struct{}
func (v *ecdsaPublicKeyKeyVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
puk := k.(*ecdsaPublicKey).pubKey
sm2pk := sm2.PublicKey{
Curve: puk.Curve,
X: puk.X,
Y: puk.Y,
}
return verifyGMSM2(&sm2pk, signature, digest, opts)
}
Sign和Verify主要是调用sm2的函数算法,其中由于ecdsa与sm2同属椭圆曲线加密算法,其在函数调用上有一定的共通性,所以也可以用ecdsa算法产生的密钥当作参数。
SM2类型的Key接口实现,包括sm2PrivateKey和sm2PublicKey。
type gmsm2PrivateKey struct {
privKey *sm2.PrivateKey
}
func (k *gmsm2PrivateKey) PublicKey() (bccsp.Key, error) {
return &gmsm2PublicKey{&k.privKey.PublicKey}, nil
}
type gmsm2PublicKey struct {
pubKey *sm2.PublicKey
}
sm4.go文件里面调用了SM4类型的签名者和校验者的接口实现。主要包含了签名和验签功能。
// AESCBCPKCS7Encrypt combines CBC encryption and PKCS7 padding
func SM4Encrypt(key, src []byte) ([]byte, error) {
// // First pad
// tmp := pkcs7Padding(src)
// // Then encrypt
// return aesCBCEncrypt(key, tmp)
dst := make([]byte, len(src))
sm4.EncryptBlock(key, dst, src)
return dst, nil
}
// AESCBCPKCS7Decrypt combines CBC decryption and PKCS7 unpadding
func SM4Decrypt(key, src []byte) ([]byte, error) {
// First decrypt
// pt, err := aesCBCDecrypt(key, src)
// if err == nil {
// return pkcs7UnPadding(pt)
// }
dst := make([]byte, len(src))
sm4.DecryptBlock(key, dst, src)
return dst, nil
}
type gmsm4Encryptor struct{}
//实现 Encryptor 接口
func (*gmsm4Encryptor) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) (ciphertext []byte, err error) {
return SM4Encrypt(k.(*gmsm4PrivateKey).privKey, plaintext)
//return AESCBCPKCS7Encrypt(k.(*sm4PrivateKey).privKey, plaintext)
// key := k.(*gmsm4PrivateKey).privKey
// var en = make([]byte, 16)
// sms4(plaintext, 16, key, en, 1)
// return en, nil
}
type gmsm4Decryptor struct{}
//实现 Decryptor 接口
func (*gmsm4Decryptor) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts) (plaintext []byte, err error) {
return SM4Decrypt(k.(*gmsm4PrivateKey).privKey, ciphertext)
// var dc = make([]byte, 16)
// key := k.(*gmsm4PrivateKey).privKey
// sms4(ciphertext, 16, key, dc, 0)
// return dc, nil
}
SM4类型的Key接口实现。
//定义国密 SM4 结构体,实现 bccsp Key 的接口
type gmsm4PrivateKey struct {
privKey []byte
exportable bool
}
bccsp的SW实现,SW实现方式是默认实现方式,代码在bccsp/sw。
// New 实例化 返回支持国密算法的 bccsp.BCCSP
func New(securityLevel int, hashFamily string, keyStore bccsp.KeyStore) (bccsp.BCCSP, error) {
// Init config
conf := &config{}
err := conf.setSecurityLevel(securityLevel, hashFamily)
if err != nil {
return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.Internal, "Failed initializing configuration at [%v,%v]", securityLevel, hashFamily).WrapError(err)
}
// Check KeyStore
if keyStore == nil {
return nil, errors.ErrorWithCallstack(errors.BCCSP, errors.BadRequest, "Invalid bccsp.KeyStore instance. It must be different from nil.")
}
// Set the encryptors
encryptors := make(map[reflect.Type]Encryptor)
encryptors[reflect.TypeOf(&gmsm4PrivateKey{})] = &gmsm4Encryptor{} //sm4 加密选项
// Set the decryptors
decryptors := make(map[reflect.Type]Decryptor)
decryptors[reflect.TypeOf(&gmsm4PrivateKey{})] = &gmsm4Decryptor{} //sm4 解密选项
// Set the signers
signers := make(map[reflect.Type]Signer)
signers[reflect.TypeOf(&gmsm2PrivateKey{})] = &gmsm2Signer{} //sm2 国密签名
signers[reflect.TypeOf(&ecdsaPrivateKey{})] = &ecdsaPrivateKeySigner{}
// Set the verifiers
verifiers := make(map[reflect.Type]Verifier)
verifiers[reflect.TypeOf(&gmsm2PrivateKey{})] = &gmsm2PrivateKeyVerifier{} //sm2 私钥验签
verifiers[reflect.TypeOf(&gmsm2PublicKey{})] = &gmsm2PublicKeyKeyVerifier{} //sm2 公钥验签
verifiers[reflect.TypeOf(&ecdsaPrivateKey{})] = &ecdsaPrivateKeyVerifier{}
verifiers[reflect.TypeOf(&ecdsaPublicKey{})] = &ecdsaPublicKeyKeyVerifier{}
// Set the hashers
hashers := make(map[reflect.Type]Hasher)
hashers[reflect.TypeOf(&bccsp.SHAOpts{})] = &hasher{hash: conf.hashFunction}
hashers[reflect.TypeOf(&bccsp.GMSM3Opts{})] = &hasher{hash: sm3.New} //sm3 Hash选项
hashers[reflect.TypeOf(&bccsp.SHA256Opts{})] = &hasher{hash: sha256.New}
hashers[reflect.TypeOf(&bccsp.SHA384Opts{})] = &hasher{hash: sha512.New384}
hashers[reflect.TypeOf(&bccsp.SHA3_256Opts{})] = &hasher{hash: sha3.New256}
hashers[reflect.TypeOf(&bccsp.SHA3_384Opts{})] = &hasher{hash: sha3.New384}
impl := &impl{
conf: conf,
ks: keyStore,
encryptors: encryptors,
decryptors: decryptors,
signers: signers,
verifiers: verifiers,
hashers: hashers}
// Set the key generators
keyGenerators := make(map[reflect.Type]KeyGenerator)
keyGenerators[reflect.TypeOf(&bccsp.GMSM2KeyGenOpts{})] = &gmsm2KeyGenerator{}
keyGenerators[reflect.TypeOf(&bccsp.GMSM4KeyGenOpts{})] = &gmsm4KeyGenerator{length: 32}
impl.keyGenerators = keyGenerators
// Set the key derivers
keyDerivers := make(map[reflect.Type]KeyDeriver)
impl.keyDerivers = keyDerivers
// Set the key importers
keyImporters := make(map[reflect.Type]KeyImporter)
keyImporters[reflect.TypeOf(&bccsp.GMSM4ImportKeyOpts{})] = &gmsm4ImportKeyOptsKeyImporter{}
keyImporters[reflect.TypeOf(&bccsp.GMSM2PrivateKeyImportOpts{})] = &gmsm2PrivateKeyImportOptsKeyImporter{}
keyImporters[reflect.TypeOf(&bccsp.GMSM2PublicKeyImportOpts{})] = &gmsm2PublicKeyImportOptsKeyImporter{}
keyImporters[reflect.TypeOf(&bccsp.X509PublicKeyImportOpts{})] = &x509PublicKeyImportOptsKeyImporter{bccsp: impl}
keyImporters[reflect.TypeOf(&bccsp.ECDSAGoPublicKeyImportOpts{})] = &ecdsaGoPublicKeyImportOptsKeyImporter{}
keyImporters[reflect.TypeOf(&bccsp.ECDSAPrivateKeyImportOpts{})] = &ecdsaPrivateKeyImportOptsKeyImporter{}
keyImporters[reflect.TypeOf(&bccsp.ECDSAPKIXPublicKeyImportOpts{})] = &ecdsaPKIXPublicKeyImportOptsKeyImporter{}
impl.keyImporters = keyImporters
return impl, nil
}
签名者、校验者、加密者、解密者等接口定义,包括:KeyGenerator、KeyDeriver、
KeyImporter、Hasher、Signer、Verifier、Encryptor和Decryptor。
只存在定义,并无实现。
bccsp的sw实现的配置定义。
func (conf *config) setSecurityLevel(securityLevel int, hashFamily string) (err error) {
err = conf.setSecurityLevelGMSM3(securityLevel)
return
}
func (conf *config) setSecurityLevelGMSM3(level int) (err error) {
switch level {
case 256:
conf.ellipticCurve = elliptic.P256()
conf.hashFunction = sm3.New
conf.rsaBitLength = 2048
conf.aesBitLength = 32
case 384:
conf.ellipticCurve = elliptic.P384()
conf.hashFunction = sm3.New
conf.rsaBitLength = 3072
conf.aesBitLength = 32
default:
err = fmt.Errorf("Security level not supported [%d]", level)
}
return
}
dummy类型的KeyStore接口实现,即dummyKeyStore,用于暂时性的Key,保存在内
存中,系统关闭即消失。
file类型的KeyStore接口实现,即fileBasedKeyStore,用于长期的Key,保存在文件中。
// GetKey returns a key object whose SKI is the one passed.
func (ks *fileBasedKeyStore) GetKey(ski []byte) (k bccsp.Key, err error) {
// Validate arguments
if len(ski) == 0 {
return nil, errors.New("Invalid SKI. Cannot be of zero length.")
}
suffix := ks.getSuffix(hex.EncodeToString(ski))
switch suffix {
case "key":
// Load the key
key, err := ks.loadKey(hex.EncodeToString(ski))
if err != nil {
return nil, fmt.Errorf("Failed loading key [%x] [%s]", ski, err)
}
return &gmsm4PrivateKey{key, false}, nil
case "sk":
// Load the private key
key, err := ks.loadPrivateKey(hex.EncodeToString(ski))
if err != nil {
return nil, fmt.Errorf("Failed loading secret key [%x] [%s]", ski, err)
}
switch key.(type) {
case *sm2.PrivateKey:
return &gmsm2PrivateKey{key.(*sm2.PrivateKey)}, nil
default:
return nil, errors.New("Secret key type not recognized")
}
case "pk":
// Load the public key
key, err := ks.loadPublicKey(hex.EncodeToString(ski))
if err != nil {
return nil, fmt.Errorf("Failed loading public key [%x] [%s]", ski, err)
}
switch key.(type) {
case *sm2.PublicKey:
return &gmsm2PublicKey{key.(*sm2.PublicKey)}, nil
default:
return nil, errors.New("Public key type not recognized")
}
default:
return ks.searchKeystoreForSKI(ski)
}
}
// StoreKey stores the key k in this KeyStore.
// If this KeyStore is read only then the method will fail.
func (ks *fileBasedKeyStore) StoreKey(k bccsp.Key) (err error) {
if ks.readOnly {
return errors.New("Read only KeyStore")
}
if k == nil {
return errors.New("Invalid key. It must be different from nil")
}
switch k.(type) {
case *gmsm2PrivateKey:
kk := k.(*gmsm2PrivateKey)
err = ks.storePrivateKey(hex.EncodeToString(k.SKI()), kk.privKey)
if err != nil {
return fmt.Errorf("Failed storing GMSM2 private key [%s]", err)
}
case *gmsm2PublicKey:
kk := k.(*gmsm2PublicKey)
err = ks.storePublicKey(hex.EncodeToString(k.SKI()), kk.pubKey)
if err != nil {
return fmt.Errorf("Failed storing GMSM2 public key [%s]", err)
}
case *gmsm4PrivateKey:
kk := k.(*gmsm4PrivateKey)
// keypath := ks.getPathForAlias(hex.EncodeToString(k.SKI()), "key")
err = ks.storeKey(hex.EncodeToString(k.SKI()), kk.privKey)
if err != nil {
return fmt.Errorf("Failed storing GMSM4 key [%s]", err)
}
default:
return fmt.Errorf("Key type not reconigned [%s]", k)
}
return
}
KeyGenerator接口实现,包括aesKeyGenerator、ecdsaKeyGenerator、sm2Generator(新增)、sm4Generator(新增)。
//定义国密SM2 keygen 结构体,实现 KeyGenerator 接口
type gmsm2KeyGenerator struct {
}
func (gm *gmsm2KeyGenerator) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
//调用 SM2的注册证书方法
privKey, err := sm2.GenerateKey()
if err != nil {
return nil, fmt.Errorf("Failed generating GMSM2 key [%s]", err)
}
return &gmsm2PrivateKey{privKey}, nil
}
//定义国密SM4 keygen 结构体,实现 KeyGenerator 接口
type gmsm4KeyGenerator struct {
length int
}
func (gm *gmsm4KeyGenerator) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
lowLevelKey, err := GetRandomBytes(int(gm.length))
if err != nil {
return nil, fmt.Errorf("Failed generating GMSM4 %d key [%s]", gm.length, err)
}
return &gmsm4PrivateKey{lowLevelKey, false}, nil
}
KeyDeriver接口实现,包括aesPrivateKeyKeyDeriver、ecdsaPrivateKeyKeyDeriver和
ecdsaPublicKeyKeyDeriver、smPublicKeyKeyDeriver(新增)。
//定义国密 Key的驱动 ,实现 KeyDeriver 接口
type smPublicKeyKeyDeriver struct{}
func (kd *smPublicKeyKeyDeriver) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) {
return nil, errors.New("Not implemented")
}
KeyImporter接口实现,包括aes256ImportKeyOptsKeyImporter、
ecdsaPKIXPublicKeyImportOptsKeyImporter、ecdsaPrivateKeyImportOptsKeyImporter、
ecdsaGoPublicKeyImportOptsKeyImporter、hmacImportKeyOptsKeyImporter和
x509PublicKeyImportOptsKeyImporter、sm4ImportKeyOptsKeyImporter(新增)、sm2PrivateKeyImportOptsKeyImporter(新增)、sm2PublicKeyImportOptsKeyImporter(新增)。
//实现内部的 KeyImporter 接口
type gmsm4ImportKeyOptsKeyImporter struct{}
func (*gmsm4ImportKeyOptsKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) {
sm4Raw, ok := raw.([]byte)
if !ok {
return nil, errors.New("Invalid raw material. Expected byte array.")
}
if sm4Raw == nil {
return nil, errors.New("Invalid raw material. It must not be nil.")
}
return &gmsm4PrivateKey{utils.Clone(sm4Raw), false}, nil
}
type gmsm2PrivateKeyImportOptsKeyImporter struct{}
func (*gmsm2PrivateKeyImportOptsKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) {
der, ok := raw.([]byte)
if !ok {
return nil, errors.New("[GMSM2PrivateKeyImportOpts] Invalid raw material. Expected byte array.")
}
if len(der) == 0 {
return nil, errors.New("[GMSM2PrivateKeyImportOpts] Invalid raw. It must not be nil.")
}
// lowLevelKey, err := utils.DERToPrivateKey(der)
// if err != nil {
// return nil, fmt.Errorf("Failed converting PKIX to GMSM2 public key [%s]", err)
// }
// gmsm2SK, ok := lowLevelKey.(*sm2.PrivateKey)
// if !ok {
// return nil, errors.New("Failed casting to GMSM2 private key. Invalid raw material.")
// }
//gmsm2SK, err := sm2.ParseSM2PrivateKey(der)
gmsm2SK, err := sm2.ParsePKCS8UnecryptedPrivateKey(der)
if err != nil {
return nil, fmt.Errorf("Failed converting to GMSM2 private key [%s]", err)
}
return &gmsm2PrivateKey{gmsm2SK}, nil
}
type gmsm2PublicKeyImportOptsKeyImporter struct{}
func (*gmsm2PublicKeyImportOptsKeyImporter) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) {
der, ok := raw.([]byte)
if !ok {
return nil, errors.New("[GMSM2PublicKeyImportOpts] Invalid raw material. Expected byte array.")
}
if len(der) == 0 {
return nil, errors.New("[GMSM2PublicKeyImportOpts] Invalid raw. It must not be nil.")
}
// lowLevelKey, err := utils.DERToPrivateKey(der)
// if err != nil {
// return nil, fmt.Errorf("Failed converting PKIX to GMSM2 public key [%s]", err)
// }
// gmsm2SK, ok := lowLevelKey.(*sm2.PrivateKey)
// if !ok {
// return nil, errors.New("Failed casting to GMSM2 private key. Invalid raw material.")
// }
gmsm2SK, err := sm2.ParseSm2PublicKey(der)
if err != nil {
return nil, fmt.Errorf("Failed converting to GMSM2 public key [%s]", err)
}
return &gmsm2PublicKey{gmsm2SK}, nil
}
Hasher接口实现,即hasher。