上次看了所有的配置文件的生成,今天讲一下fabric环境中所有的证书生成,以及fabric支持的算法,所有的算法只要放在bccsp包中,这里有各种算法的实现工厂,没有算法都自己的单独的包,这里面我们回用到,回到正题,我们上次看到了generate()方法中,我们只看了renderOrgSpec()方法,生成配置文件。
我们继续看源代码:
for _, orgSpec := range config.PeerOrgs {
err = renderOrgSpec(&orgSpec, "peer")
if err != nil {
fmt.Printf("Error processing peer configuration: %s", err)
os.Exit(-1)
}
generatePeerOrg(*outputDir, orgSpec)
}
generatePeerOrgs()方法,生成所有的证书文件以及tls证书文件。
func generatePeerOrg(baseDir string, orgSpec OrgSpec) {
orgName := orgSpec.Domain//获得组织的域名
fmt.Println(orgName)
// generate CAs
orgDir := filepath.Join(baseDir, "peerOrganizations", orgName)//生成orgDir的文件目录
caDir := filepath.Join(orgDir, "ca")//生成ca证书的目录机构
tlsCADir := filepath.Join(orgDir, "tlsca")//tls证书的目录
mspDir := filepath.Join(orgDir, "msp")//mspde的目录
peersDir := filepath.Join(orgDir, "peers")//peer节点的目录
usersDir := filepath.Join(orgDir, "users")//所有用户的目录
adminCertsDir := filepath.Join(mspDir, "admincerts")//admin证书的目录
// generate signing CA 生成Ca证书,以及所有Ca的组织机构,国家,邮政编码等证书生成的元素。
signCA, err := ca.NewCA(caDir, orgName, orgSpec.CA.CommonName, orgSpec.CA.Country, orgSpec.CA.Province, orgSpec.CA.Locality, orgSpec.CA.OrganizationalUnit, orgSpec.CA.StreetAddress, orgSpec.CA.PostalCode)
if err != nil {
fmt.Printf("Error generating signCA for org %s:\n%v\n", orgName, err)
os.Exit(1)
}
// generate TLS CA
tlsCA, err := ca.NewCA(tlsCADir, orgName, "tls"+orgSpec.CA.CommonName, orgSpec.CA.Country, orgSpec.CA.Province, orgSpec.CA.Locality, orgSpec.CA.OrganizationalUnit, orgSpec.CA.StreetAddress, orgSpec.CA.PostalCode)
if err != nil {
fmt.Printf("Error generating tlsCA for org %s:\n%v\n", orgName, err)
os.Exit(1)
}
err = msp.GenerateVerifyingMSP(mspDir, signCA, tlsCA, orgSpec.EnableNodeOUs)
if err != nil {
fmt.Printf("Error generating MSP for org %s:\n%v\n", orgName, err)
os.Exit(1)
}
generateNodes(peersDir, orgSpec.Specs, signCA, tlsCA, msp.PEER, orgSpec.EnableNodeOUs)
// TODO: add ability to specify usernames
users := []NodeSpec{}
for j := 1; j <= orgSpec.Users.Count; j++ {
user := NodeSpec{
CommonName: fmt.Sprintf("%s%d@%s", userBaseName, j, orgName),
}
users = append(users, user)
}
// add an admin user
adminUser := NodeSpec{
CommonName: fmt.Sprintf("%s@%s", adminBaseName, orgName),
}
users = append(users, adminUser)
generateNodes(usersDir, users, signCA, tlsCA, msp.CLIENT, orgSpec.EnableNodeOUs)
// copy the admin cert to the org's MSP admincerts
err = copyAdminCert(usersDir, adminCertsDir, adminUser.CommonName)
if err != nil {
fmt.Printf("Error copying admin cert for org %s:\n%v\n",
orgName, err)
os.Exit(1)
}
// copy the admin cert to each of the org's peer's MSP admincerts
for _, spec := range orgSpec.Specs {
err = copyAdminCert(usersDir,
filepath.Join(peersDir, spec.CommonName, "msp", "admincerts"), adminUser.CommonName)
if err != nil {
fmt.Printf("Error copying admin cert for org %s peer %s:\n%v\n",
orgName, spec.CommonName, err)
os.Exit(1)
}
}
}
NewA()方法用于生成所有的证书
func NewCA(baseDir, org, name, country, province, locality, orgUnit, streetAddress, postalCode string) (*CA, error) {
var response error
var ca *CA//构件一个证书对象
err := os.MkdirAll(baseDir, 0755)//穿件证书的目录,并设置权限
if err == nil {
priv, signer, err := csp.GeneratePrivateKey(baseDir)//生成私钥
response = err
if err == nil {
// get public signing certificate
ecPubKey, err := csp.GetECPublicKey(priv)//生成公钥
response = err
if err == nil {
template := x509Template()//创建X509Template模板
//this is a CA
template.IsCA = true
template.KeyUsage |= x509.KeyUsageDigitalSignature |
x509.KeyUsageKeyEncipherment | x509.KeyUsageCertSign |
x509.KeyUsageCRLSign//这是key的用途
template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
//set the organization for the subject生成证书主题
subject := subjectTemplateAdditional(country, province, locality, orgUnit, streetAddress, postalCode)
subject.Organization = []string{org}//设置证书组织机构
subject.CommonName = name//设置证书的服务器的主机名
template.Subject = subject//主题
template.SubjectKeyId = priv.SKI()//获得私钥的SKI
x509Cert, err := genCertificateECDSA(baseDir, name, &template, &template,
ecPubKey, signer)//获得证书
response = err
if err == nil {
ca = &CA{//证书对象赋值
Name: name,
Signer: signer,
SignCert: x509Cert,
Country: country,
Province: province,
Locality: locality,
OrganizationalUnit: orgUnit,
StreetAddress: streetAddress,
PostalCode: postalCode,
}
}
}
}
}
return ca, response
}
这个方法中 csp.GeneratePrivateKey()方法是 csp包下的GeneratePrivateKey()方法
func GeneratePrivateKey(keystorePath string) (bccsp.Key,
crypto.Signer, error) {
var err error
var priv bccsp.Key
var s crypto.Signer
opts := &factory.FactoryOpts{//设置factoryOpts的参数
ProviderName: "SW",//设置提供者的别名
SwOpts: &factory.SwOpts{
HashFamily: "SHA2",//hash的算法
SecLevel: 256,//长度
FileKeystore: &factory.FileKeystoreOpts{//设置文件keyStore的存放位置
KeyStorePath: keystorePath,
},
},
}
csp, err := factory.GetBCCSPFromOpts(opts)//根据参数获得具体的算法对象
if err == nil {
// generate a key
priv, err = csp.KeyGen(&bccsp.ECDSAP256KeyGenOpts{Temporary: false})//取得ECDSA算法 256长度的可以,Temporary 表明是否是临时key,false表明不是临时的。
if err == nil {
// create a crypto.Signer
s, err = signer.New(csp, priv)//拿到私钥签名
}
}
return priv, s, err
}
我们再看一下
factory.GetBCCSPFromOpts(opts) 方法,这个属于bccsp包中factory中的pkcs11.go中的
func GetBCCSPFromOpts(config *FactoryOpts) (bccsp.BCCSP, error) {
var f BCCSPFactory
switch config.ProviderName {//取得设置的算法工厂的别名
case "SW"://根据不同的别名取得不同的算法工厂。
f = &SWFactory{}
case "PKCS11":
f = &PKCS11Factory{}
case "PLUGIN":
f = &PluginFactory{}
default:
return nil, errors.Errorf("Could not find BCCSP, no '%s' provider", config.ProviderName)
}
csp, err := f.Get(config)//每个算法工厂都实现了Get方法
if err != nil {
return nil, errors.Wrapf(err, "Could not initialize BCCSP %s", f.Name())
}
return csp, nil
}
我们以SWFactory为例子,看bccsp.BCCSP如何生成。
const (
// SoftwareBasedFactoryName is the name of the factory of the software-based BCCSP implementation
SoftwareBasedFactoryName = "SW"//设置算法工厂的别名
)
// SWFactory is the factory of the software-based BCCSP.
type SWFactory struct{}//构件一个空的对象
// Name returns the name of this factory
func (f *SWFactory) Name() string {//获得工厂的别名
return SoftwareBasedFactoryName
}
// Get returns an instance of BCCSP using Opts. 根据Opts的方法获得Bccsp.BCCSP对象
func (f *SWFactory) Get(config *FactoryOpts) (bccsp.BCCSP, error) {
// Validate arguments
if config == nil || config.SwOpts == nil {//如果配置文件对象为空,报错
return nil, errors.New("Invalid config. It must not be nil.")
}
swOpts := config.SwOpts
var ks bccsp.KeyStore//设置key存储的对象
if swOpts.Ephemeral == true {//如果是临时对象
ks = sw.NewDummyKeyStore()//ks赋值为空结构体
} else if swOpts.FileKeystore != nil {//如果keyStore存的不为空
fks, err := sw.NewFileBasedKeyStore(nil, swOpts.FileKeystore.KeyStorePath, false)//生成KeyStore文件
if err != nil {
return nil, errors.Wrapf(err, "Failed to initialize software key store")
}
ks = fks
} else {
// Default to DummyKeystore
ks = sw.NewDummyKeyStore()
}
return sw.NewWithParams(swOpts.SecLevel, swOpts.HashFamily, ks)
}
// SwOpts contains options for the SWFactory
type SwOpts struct {
// Default algorithms when not specified (Deprecated?)
SecLevel int `mapstructure:"security" json:"security" yaml:"Security"`
HashFamily string `mapstructure:"hash" json:"hash" yaml:"Hash"`
// Keystore Options
Ephemeral bool `mapstructure:"tempkeys,omitempty" json:"tempkeys,omitempty"`
FileKeystore *FileKeystoreOpts `mapstructure:"filekeystore,omitempty" json:"filekeystore,omitempty" yaml:"FileKeyStore"`
DummyKeystore *DummyKeystoreOpts `mapstructure:"dummykeystore,omitempty" json:"dummykeystore,omitempty"`
}
// Pluggable Keystores, could add JKS, P12, etc..
type FileKeystoreOpts struct {
KeyStorePath string `mapstructure:"keystore" yaml:"KeyStore"`
}
type DummyKeystoreOpts struct{}
然后看一下sw.NewWithParams()方法
func NewWithParams(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.Wrapf(err, "Failed initializing configuration at [%v,%v]", securityLevel, hashFamily)
}
swbccsp, err := New(keyStore)
if err != nil {
return nil, err
}
// Notice that errors are ignored here because some test will fail if one
// of the following call fails.
// Set the encryptors 设置加密
swbccsp.AddWrapper(reflect.TypeOf(&aesPrivateKey{}), &aescbcpkcs7Encryptor{})
// Set the decryptors 设置解密
swbccsp.AddWrapper(reflect.TypeOf(&aesPrivateKey{}), &aescbcpkcs7Decryptor{})
// Set the signers 设置签名
swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPrivateKey{}), &ecdsaSigner{})
swbccsp.AddWrapper(reflect.TypeOf(&rsaPrivateKey{}), &rsaSigner{})
// Set the verifiers 验证
swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPrivateKey{}), &ecdsaPrivateKeyVerifier{})
swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPublicKey{}), &ecdsaPublicKeyKeyVerifier{})
swbccsp.AddWrapper(reflect.TypeOf(&rsaPrivateKey{}), &rsaPrivateKeyVerifier{})
swbccsp.AddWrapper(reflect.TypeOf(&rsaPublicKey{}), &rsaPublicKeyKeyVerifier{})
// Set the hashers 设置支持的算法
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.SHAOpts{}), &hasher{hash: conf.hashFunction})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.SHA256Opts{}), &hasher{hash: sha256.New})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.SHA384Opts{}), &hasher{hash: sha512.New384})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.SHA3_256Opts{}), &hasher{hash: sha3.New256})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.SHA3_384Opts{}), &hasher{hash: sha3.New384})
// Set the key generators 所有的key的参数
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.ECDSAKeyGenOpts{}), &ecdsaKeyGenerator{curve: conf.ellipticCurve})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.ECDSAP256KeyGenOpts{}), &ecdsaKeyGenerator{curve: elliptic.P256()})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.ECDSAP384KeyGenOpts{}), &ecdsaKeyGenerator{curve: elliptic.P384()})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.AESKeyGenOpts{}), &aesKeyGenerator{length: conf.aesBitLength})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.AES256KeyGenOpts{}), &aesKeyGenerator{length: 32})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.AES192KeyGenOpts{}), &aesKeyGenerator{length: 24})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.AES128KeyGenOpts{}), &aesKeyGenerator{length: 16})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.RSAKeyGenOpts{}), &rsaKeyGenerator{length: conf.rsaBitLength})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.RSA1024KeyGenOpts{}), &rsaKeyGenerator{length: 1024})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.RSA2048KeyGenOpts{}), &rsaKeyGenerator{length: 2048})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.RSA3072KeyGenOpts{}), &rsaKeyGenerator{length: 3072})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.RSA4096KeyGenOpts{}), &rsaKeyGenerator{length: 4096})
// Set the key generators key的的算法驱动
swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPrivateKey{}), &ecdsaPrivateKeyKeyDeriver{})
swbccsp.AddWrapper(reflect.TypeOf(&ecdsaPublicKey{}), &ecdsaPublicKeyKeyDeriver{})
swbccsp.AddWrapper(reflect.TypeOf(&aesPrivateKey{}), &aesPrivateKeyKeyDeriver{conf: conf})
// Set the key importers 所有key方法的实现
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.AES256ImportKeyOpts{}), &aes256ImportKeyOptsKeyImporter{})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.HMACImportKeyOpts{}), &hmacImportKeyOptsKeyImporter{})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.ECDSAPKIXPublicKeyImportOpts{}), &ecdsaPKIXPublicKeyImportOptsKeyImporter{})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.ECDSAPrivateKeyImportOpts{}), &ecdsaPrivateKeyImportOptsKeyImporter{})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.ECDSAGoPublicKeyImportOpts{}), &ecdsaGoPublicKeyImportOptsKeyImporter{})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.RSAGoPublicKeyImportOpts{}), &rsaGoPublicKeyImportOptsKeyImporter{})
swbccsp.AddWrapper(reflect.TypeOf(&bccsp.X509PublicKeyImportOpts{}), &x509PublicKeyImportOptsKeyImporter{bccsp: swbccsp})
return swbccsp, nil
}
返回 bccsp.BCCSP对象。
再回到
csp.GeneratePrivateKey()方法,然后生成秘钥对 csp.KeyGen()方法,这个方法是现在sw包中impl.go中
func (csp *CSP) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) {
// Validate arguments
if opts == nil {
return nil, errors.New("Invalid Opts parameter. It must not be nil.")
}
keyGenerator, found := csp.keyGenerators[reflect.TypeOf(opts)]//获得opts的类型,然后获得key的生成器
if !found {
return nil, errors.Errorf("Unsupported 'KeyGenOpts' provided [%v]", opts)
}
k, err = keyGenerator.KeyGen(opts)//根据配置参数生成key
if err != nil {
return nil, errors.Wrapf(err, "Failed generating key with opts [%v]", opts)
}
// If the key is not Ephemeral, store it.
if !opts.Ephemeral() {//是不是临时key
// Store the key
err = csp.ks.StoreKey(k)//不是的话,写入到keyStore中保存
if err != nil {
return nil, errors.Wrapf(err, "Failed storing key [%s]", opts.Algorithm())
}
}
return k, nil
}
csp.GeneratePrivateKey()方法,然后生成签名的singer.New,这个方法是现在bccsp/signer/signer.go中
func New(csp bccsp.BCCSP, key bccsp.Key) (crypto.Signer, error) {
// Validate arguments
if csp == nil {
return nil, errors.New("bccsp instance must be different from nil.")
}
if key == nil {
return nil, errors.New("key must be different from nil.")
}
if key.Symmetric() {
return nil, errors.New("key must be asymmetric.")
}
// Marshall the bccsp public key as a crypto.PublicKey
pub, err := key.PublicKey()
if err != nil {
return nil, errors.Wrap(err, "failed getting public key")
}
raw, err := pub.Bytes()
if err != nil {
return nil, errors.Wrap(err, "failed marshalling public key")
}
pk, err := utils.DERToPublicKey(raw)
if err != nil {
return nil, errors.Wrap(err, "failed marshalling der to public key")
}
return &bccspCryptoSigner{csp, key, pk}, nil
}
构件对象 返回公钥,还有bccspCryptoSigner对象。
再回到NewCA()方法 生成私钥,然后再获得公钥,
ecPubKey, err := csp.GetECPublicKey(priv)
再返回到generatePeerOrg()方法
生成tlsCa证书,只是目录不一样而已,然后验证MSP的。
今天先写到这里把,只是把证书的生成讲完,也只是流水式的代码分析,问题是还没有说完。。。验证MSP的方法下次再讲。如果有什么不妥的地方,请大家指正。谢谢