crypto是blockchain中加密技术功能的实现,当中包含了椭圆曲线加密和SHA256等加密算法等。接下来将对其核心部分进行解析。

elliptic

返回加密层中使用的默认椭圆曲线

func GetDefaultCurve() elliptic.Curve {
return defaultCurve
}

hash

返回加密层中使用的默认哈希值

func GetDefaultHash() func() hash.Hash {
return defaultHash
}

init

在给定的安全级别内初始化password层

func InitSecurityLevel(level int) (err error) {
initOnce.Do(func() {
switch level {
case 256:
defaultCurve = elliptic.P256()
defaultHash = sha3.New256
case 384:
defaultCurve = elliptic.P384()
defaultHash = sha3.New384
default:
err = fmt.Errorf("Security level not supported [%d]", level)
}
}) return
}

generic

generic位于ecies包下

engine

aesEncrypt

ase加密

func aesEncrypt(key, plain []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
} text := make([]byte, aes.BlockSize+len(plain))
iv := text[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
} cfb := cipher.NewCFBEncrypter(block, iv)
cfb.XORKeyStream(text[aes.BlockSize:], plain) return text, nil
}

aesDecrypt

aes解密

func aesDecrypt(key, text []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
} if len(text) < aes.BlockSize {
return nil, errors.New("cipher text too short")
} cfb := cipher.NewCFBDecrypter(block, text[:aes.BlockSize])
plain := make([]byte, len(text)-aes.BlockSize)
cfb.XORKeyStream(plain, text[aes.BlockSize:]) return plain, nil
}

eciesGenerateKey

ECIES生成密钥

func eciesGenerateKey(rand io.Reader, curve elliptic.Curve, params *Params) (*ecdsa.PrivateKey, error) {
return ecdsa.GenerateKey(curve, rand)
}

eciesEncrypt

func eciesEncrypt(rand io.Reader, pub *ecdsa.PublicKey, s1, s2 []byte, plain []byte) ([]byte, error) {
params := pub.Curve.Params() //选择带有椭圆曲线域參数相关的暂时椭圆曲线密钥对
priv, Rx, Ry, err := elliptic.GenerateKey(pub.Curve, rand)
//fmt.Printf("Rx %s\n", utils.EncodeBase64(Rx.Bytes()))
//fmt.Printf("Ry %s\n", utils.EncodeBase64(Ry.Bytes())) // 转换 R=(Rx,Ry) 为R字节串
// 这是未压缩的
Rb := elliptic.Marshal(pub.Curve, Rx, Ry) // 从暂时的私钥k得出一个公钥元素z。而且将字节串z转化为Z
z, _ := params.ScalarMult(pub.X, pub.Y, priv)
Z := z.Bytes()
//fmt.Printf("Z %s\n", utils.EncodeBase64(Z)) //借助Z中生成长度为ecnKeyLen+macKeyLen的公钥数据K // ans s1
kE := make([]byte, 32)
kM := make([]byte, 32)
hkdf := hkdf.New(conf.GetDefaultHash(), Z, s1, nil)
_, err = hkdf.Read(kE)
if err != nil {
return nil, err
}
_, err = hkdf.Read(kM)
if err != nil {
return nil, err
} //使用对称加密方案的加密运算加密m在EK中的密文EM
EM, err := aesEncrypt(kE, plain) //使用MAC方案的标签操作来计算EM上的标签D||S2
mac := hmac.New(conf.GetDefaultHash(), kM)
mac.Write(EM)
if len(s2) > 0 {
mac.Write(s2)
}
D := mac.Sum(nil) // Output R,EM,D
ciphertext := make([]byte, len(Rb)+len(EM)+len(D))
//fmt.Printf("Rb %s\n", utils.EncodeBase64(Rb))
//fmt.Printf("EM %s\n", utils.EncodeBase64(EM))
//fmt.Printf("D %s\n", utils.EncodeBase64(D))
copy(ciphertext, Rb)
copy(ciphertext[len(Rb):], EM)
copy(ciphertext[len(Rb)+len(EM):], D) return ciphertext, nil
}

eciesDecrypt

func eciesDecrypt(priv *ecdsa.PrivateKey, s1, s2 []byte, ciphertext []byte) ([]byte, error) {
params := priv.Curve.Params() var (
rLen int
hLen int = conf.GetDefaultHash()().Size()
mStart int
mEnd int
) //fmt.Printf("Decrypt\n")
switch ciphertext[0] {
case 2, 3:
rLen = ((priv.PublicKey.Curve.Params().BitSize + 7) / 8) + 1
if len(ciphertext) < (rLen + hLen + 1) {
return nil, errors.New("Invalid ciphertext")
}
break
case 4:
rLen = 2*((priv.PublicKey.Curve.Params().BitSize+7)/8) + 1
if len(ciphertext) < (rLen + hLen + 1) {
return nil, errors.New("Invalid ciphertext")
}
break default:
return nil, errors.New("Invalid ciphertext")
} mStart = rLen
mEnd = len(ciphertext) - hLen
//fmt.Printf("Rb %s\n", utils.EncodeBase64(ciphertext[:rLen])) Rx, Ry := elliptic.Unmarshal(priv.Curve, ciphertext[:rLen])
if Rx == nil {
return nil, errors.New("Invalid ephemeral PK")
}
if !priv.Curve.IsOnCurve(Rx, Ry) {
return nil, errors.New("Invalid point on curve")
}
//fmt.Printf("Rx %s\n", utils.EncodeBase64(Rx.Bytes()))
//fmt.Printf("Ry %s\n", utils.EncodeBase64(Ry.Bytes())) // 从暂时的私钥k得出一个公钥z。并转换z到字节串Z
z, _ := params.ScalarMult(Rx, Ry, priv.D.Bytes())
Z := z.Bytes()
//fmt.Printf("Z %s\n", utils.EncodeBase64(Z)) kE := make([]byte, 32)
kM := make([]byte, 32)
hkdf := hkdf.New(conf.GetDefaultHash(), Z, s1, nil)
_, err := hkdf.Read(kE)
if err != nil {
return nil, err
}
_, err = hkdf.Read(kM)
if err != nil {
return nil, err
} // 使用MAC方案的标签操作来计算EM上的标签,再对照D||S2
mac := hmac.New(conf.GetDefaultHash(), kM)
mac.Write(ciphertext[mStart:mEnd])
if len(s2) > 0 {
mac.Write(s2)
}
D := mac.Sum(nil) //fmt.Printf("EM %s\n", utils.EncodeBase64(ciphertext[mStart:mEnd]))
//fmt.Printf("D' %s\n", utils.EncodeBase64(D))
//fmt.Printf("D %s\n", utils.EncodeBase64(ciphertext[mEnd:]))
if subtle.ConstantTimeCompare(ciphertext[mEnd:], D) != 1 {
return nil, errors.New("Tag check failed")
} // 使用对称加密方案的解密操作使用明文EK解密EM plaintext, err := aesDecrypt(kE, ciphertext[mStart:mEnd]) return plaintext, err
}

es

func (es *encryptionSchemeImpl) Init(params ecies.AsymmetricCipherParameters) error {
if params == nil {
return ecies.ErrInvalidKeyParameter
}
es.isForEncryption = params.IsPublic()
es.params = params if es.isForEncryption {
switch pk := params.(type) {
case *publicKeyImpl:
es.pub = pk
default:
return ecies.ErrInvalidKeyParameter
}
} else {
switch sk := params.(type) {
case *secretKeyImpl:
es.priv = sk
default:
return ecies.ErrInvalidKeyParameter
}
} return nil
} func (es *encryptionSchemeImpl) Process(msg []byte) ([]byte, error) {
if es.isForEncryption {
// 加密
return eciesEncrypt(es.params.GetRand(), es.pub.pub, nil, nil, msg)
} else {
// 解密
return eciesDecrypt(es.priv.priv, nil, nil, msg)
} return nil, nil
}

kg

生成密钥

func (kg *keyGeneratorImpl) GenerateKey() (ecies.PrivateKey, error) {

    privKey, err := eciesGenerateKey(
kg.params.rand,
kg.params.curve,
kg.params.params,
)
if err != nil {
return nil, err
} return &secretKeyImpl{privKey, nil, kg.params.params, kg.params.rand}, nil
}

params

type Params struct {
Hash func() hash.Hash
hashAlgo crypto.Hash //哈希加密
Cipher func([]byte) (cipher.Block, error) //暗号
BlockSize int //块大小
KeyLen int //密钥长度
}

pk

//获取随机密钥
func (pk *publicKeyImpl) GetRand() io.Reader {
return pk.rand
}
//推断是否为公钥
func (pk *publicKeyImpl) IsPublic() bool {
return true
}

sk

func (sk *secretKeyImpl) IsPublic() bool {
return false
} func (sk *secretKeyImpl) GetRand() io.Reader {
return sk.rand
} func (sk *secretKeyImpl) GetPublicKey() ecies.PublicKey {
if sk.pub == nil {
sk.pub = &publicKeyImpl{&sk.priv.PublicKey, sk.rand, sk.params}
}
return sk.pub
}
//转换为字节
func (sks *secretKeySerializerImpl) ToBytes(key interface{}) ([]byte, error) {
switch sk := key.(type) {
case *secretKeyImpl:
return x509.MarshalECPrivateKey(sk.priv)
default:
return nil, ecies.ErrInvalidKeyParameter
} return nil, ecies.ErrInvalidKeyParameter
}
//从字节中转换私钥
func (sks *secretKeySerializerImpl) FromBytes(bytes []byte) (interface{}, error) {
key, err := x509.ParseECPrivateKey(bytes)
if err != nil {
return nil, err
} // TODO: add params here
return &secretKeyImpl{key, nil, nil, rand.Reader}, nil
}

spi

//序列化私钥
func serializePrivateKey(priv ecies.PrivateKey) ([]byte, error) {
serializer := secretKeySerializerImpl{}
return serializer.ToBytes(priv)
}
//反序列化私钥
func deserializePrivateKey(bytes []byte) (ecies.PrivateKey, error) {
serializer := secretKeySerializerImpl{}
priv, err := serializer.FromBytes(bytes)
if err != nil {
return nil, err
} return priv.(ecies.PrivateKey), nil
}
//生成非对称password
func newAsymmetricCipher() (ecies.AsymmetricCipher, error) {
return &encryptionSchemeImpl{}, nil
}
//生成私钥
func newPrivateKey(rand io.Reader, curve elliptic.Curve) (ecies.PrivateKey, error) {
kg, err := newKeyGeneratorFromCurve(rand, curve)
if err != nil {
return nil, err
}
return kg.GenerateKey()
}
//从私钥创建非对称password
func newAsymmetricCipherFromPrivateKey(priv ecies.PrivateKey) (ecies.AsymmetricCipher, error) {
es, err := newAsymmetricCipher()
if err != nil {
return nil, err
} err = es.Init(priv)
if err != nil {
return nil, err
} return es, nil
}
//从公钥创建非对称password
func newAsymmetricCipherFromPublicKey(pub ecies.PublicKey) (ecies.AsymmetricCipher, error) {
es, err := newAsymmetricCipher()
if err != nil {
return nil, err
} err = es.Init(pub)
if err != nil {
return nil, err
} return es, nil
}

crypto

cypto实现了和密钥有关的接口

var (
// 无效的密钥參数
ErrInvalidKeyParameter = errors.New("Invalid Key Parameter.") //无效的密钥生成器參数
ErrInvalidKeyGeneratorParameter = errors.New("Invalid Key Generator Parameter.")
) // 对于所有參数的通用接口
type Parameters interface { // 随机生成关联參数
GetRand() io.Reader
} // 通用接口来表示password參数
type CipherParameters interface {
Parameters
} // 通用接口来表示非对称password參数
type AsymmetricCipherParameters interface {
Parameters // 假设參数是公开的返回true,否则为false。
IsPublic() bool
} //通用接口代表非对称公钥參数
type PublicKey interface {
AsymmetricCipherParameters
} //通用接口代表非对称私钥參数
type PrivateKey interface {
AsymmetricCipherParameters // 返回关联公钥
GetPublicKey() PublicKey
} // 通用接口来表示密钥生成參数
type KeyGeneratorParameters interface {
Parameters
} // 定义密钥生成器
type KeyGenerator interface {
//初始化生成使用传递的參数
Init(params KeyGeneratorParameters) error // 生成一个新的私钥
GenerateKey() (PrivateKey, error)
} //定义了一个非对称password
type AsymmetricCipher interface {
// 使用传递的參数初始化
Init(params AsymmetricCipherParameters) error // 处理输入给出的字节数组的过程
Process(msg []byte) ([]byte, error)
} // 密钥序列化/反序列化
type KeySerializer interface {
// 转换密钥为字节
ToBytes(key interface{}) ([]byte, error) // 转换字节为密钥
FromBytes([]byte) (interface{}, error)
} // ECIES服务提供接口
type SPI interface { //从秘钥创建解密一个新的非对称password
NewAsymmetricCipherFromPrivateKey(priv PrivateKey) (AsymmetricCipher, error) //从公钥创建解密一个新的非对称password
NewAsymmetricCipherFromPublicKey(pub PublicKey) (AsymmetricCipher, error) // 从(rand, params)创建一个新的私钥
NewPrivateKey(rand io.Reader, params interface{}) (PrivateKey, error) //从(rand, params)创建一个新的公钥
NewPublicKey(rand io.Reader, params interface{}) (PublicKey, error) // 序列化私钥
SerializePrivateKey(priv PrivateKey) ([]byte, error) // 反序列化私钥
DeserializePrivateKey(bytes []byte) (PrivateKey, error)
}

aes

const (
// AES 秘钥的默认长度
AESKeyLength = 32 // 默认nonce大小
NonceSize = 24
) // 返回一个长度AESKeyLength为随机 AES 密钥
func GenAESKey() ([]byte, error) {
return GetRandomBytes(AESKeyLength)
} //基于PKCS7标准填充
func PKCS7Padding(src []byte) []byte {
padding := aes.BlockSize - len(src)%aes.BlockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(src, padtext...)
} //基于PKCS7标准反填充
func PKCS7UnPadding(src []byte) ([]byte, error) {
length := len(src)
unpadding := int(src[length-1]) if unpadding > aes.BlockSize || unpadding == 0 {
return nil, fmt.Errorf("invalid padding")
} pad := src[len(src)-unpadding:]
for i := 0; i < unpadding; i++ {
if pad[i] != byte(unpadding) {
return nil, fmt.Errorf("invalid padding")
}
} return src[:(length - unpadding)], nil
} //使用CBC模式加密
func CBCEncrypt(key, s []byte) ([]byte, error) {
// CBC模式适用于块,这种明文可能须要填充到下一个整块。 对于这种填充的一个实例,參见
// https://tools.ietf.org/html/rfc5246#section-6.2.3.2. Here we'll
// 假定所述明文已确定长度。
if len(s)%aes.BlockSize != 0 {
return nil, errors.New("plaintext is not a multiple of the block size")
} block, err := aes.NewCipher(key)
if err != nil {
return nil, err
} // 须要唯一。但并不安全。因此它是常见的包含其在密文的開始。 ciphertext := make([]byte, aes.BlockSize+len(s))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
return nil, err
} mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], s) // 要记住,密文必须经过验证是很重要的(即,通过使用加密/ HMAC)以及为了被加密是安全的。 return ciphertext, nil
} // 使用CBC模式解密
func CBCDecrypt(key, src []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
} // 须要唯一,但并不安全。 因此它是常见的包含其在密文的開始。
if len(src) < aes.BlockSize {
return nil, errors.New("ciphertext too short")
}
iv := src[:aes.BlockSize]
src = src[aes.BlockSize:] //CBC模式往往工作于整个块中
if len(src)%aes.BlockSize != 0 {
return nil, errors.New("ciphertext is not a multiple of the block size")
} mode := cipher.NewCBCDecrypter(block, iv) //能够就地工作。假设两个參数是同样的。
mode.CryptBlocks(src, src) // 假设原来的明文的长度不是块大小的倍数,加密填充时。这将在这一点被移除被加入 return src, nil
} // 结合CBC加密填充PKCS7
func CBCPKCS7Encrypt(key, src []byte) ([]byte, error) {
return CBCEncrypt(key, PKCS7Padding(src))
} //结合CBC加密反填充填充PKCS7
func CBCPKCS7Decrypt(key, src []byte) ([]byte, error) {
pt, err := CBCDecrypt(key, src)
if err != nil {
return nil, err
} original, err := PKCS7UnPadding(pt)
if err != nil {
return nil, err
} return original, nil
}

cert

var (
// TCertEncTCertIndex为TCertIndex的对象标识符
TCertEncTCertIndex = asn1.ObjectIdentifier{1, 2, 3, 4, 5, 6, 7}
) // 将der转换为X509
func DERToX509Certificate(asn1Data []byte) (*x509.Certificate, error) {
return x509.ParseCertificate(asn1Data)
} // 将pem转换为X509
func PEMtoCertificate(raw []byte) (*x509.Certificate, error) {
block, _ := pem.Decode(raw)
if block == nil {
return nil, errors.New("No PEM block available")
} if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
return nil, errors.New("Not a valid CERTIFICATE PEM block")
} cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
} return cert, nil
} // 将 pem 转换为der
func PEMtoDER(raw []byte) ([]byte, error) {
block, _ := pem.Decode(raw)
if block == nil {
return nil, errors.New("No PEM block available")
} if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
return nil, errors.New("Not a valid CERTIFICATE PEM block")
} return block.Bytes, nil
} // 将 pem 转换为x509和der
func PEMtoCertificateAndDER(raw []byte) (*x509.Certificate, []byte, error) {
block, _ := pem.Decode(raw)
if block == nil {
return nil, nil, errors.New("No PEM block available")
} if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
return nil, nil, errors.New("Not a valid CERTIFICATE PEM block")
} cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, nil, err
} return cert, block.Bytes, nil
} // 将der转换为pem
func DERCertToPEM(der []byte) []byte {
return pem.EncodeToMemory(
&pem.Block{
Type: "CERTIFICATE",
Bytes: der,
},
)
} // 返回请求的关键扩展。这也从未处理的关键扩展的列表中移除
func GetCriticalExtension(cert *x509.Certificate, oid asn1.ObjectIdentifier) ([]byte, error) {
for i, ext := range cert.UnhandledCriticalExtensions {
if IntArrayEquals(ext, oid) {
cert.UnhandledCriticalExtensions = append(cert.UnhandledCriticalExtensions[:i], cert.UnhandledCriticalExtensions[i+1:]...) break
}
} for _, ext := range cert.Extensions {
if IntArrayEquals(ext.Id, oid) {
return ext.Value, nil
}
} return nil, errors.New("Failed retrieving extension.")
} // 创建一个自签名证书
func NewSelfSignedCert() ([]byte, interface{}, error) {
privKey, err := NewECDSAKey()
if err != nil {
return nil, nil, err
} testExtKeyUsage := []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}
testUnknownExtKeyUsage := []asn1.ObjectIdentifier{[]int{1, 2, 3}, []int{2, 59, 1}}
extraExtensionData := []byte("extra extension")
commonName := "test.example.com"
template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
CommonName: commonName,
Organization: []string{"Σ Acme Co"},
Country: []string{"US"},
ExtraNames: []pkix.AttributeTypeAndValue{
{
Type: []int{2, 5, 4, 42},
Value: "Gopher",
},
// 应该所有覆盖Country.
{
Type: []int{2, 5, 4, 6},
Value: "NL",
},
},
},
NotBefore: time.Unix(1000, 0),
NotAfter: time.Unix(100000, 0), SignatureAlgorithm: x509.ECDSAWithSHA384, SubjectKeyId: []byte{1, 2, 3, 4},
KeyUsage: x509.KeyUsageCertSign, ExtKeyUsage: testExtKeyUsage,
UnknownExtKeyUsage: testUnknownExtKeyUsage, BasicConstraintsValid: true,
IsCA: true, OCSPServer: []string{"http://ocsp.example.com"},
IssuingCertificateURL: []string{"http://crt.example.com/ca1.crt"}, DNSNames: []string{"test.example.com"},
EmailAddresses: []string{"gopher@golang.org"},
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1).To4(), net.ParseIP("2001:4860:0:2001::68")}, PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
PermittedDNSDomains: []string{".example.com", "example.com"}, CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"}, ExtraExtensions: []pkix.Extension{
{
Id: []int{1, 2, 3, 4},
Value: extraExtensionData,
},
},
} cert, err := x509.CreateCertificate(rand.Reader, &template, &template, &privKey.PublicKey, privKey)
if err != nil {
return nil, nil, err
} return cert, privKey, nil
} //通过密钥检查证书的公钥
func CheckCertPKAgainstSK(x509Cert *x509.Certificate, privateKey interface{}) error {
switch pub := x509Cert.PublicKey.(type) {
case *rsa.PublicKey:
priv, ok := privateKey.(*rsa.PrivateKey)
if !ok {
return errors.New("Private key type does not match public key type")
}
if pub.N.Cmp(priv.N) != 0 {
return errors.New("Private key does not match public key")
}
case *ecdsa.PublicKey:
priv, ok := privateKey.(*ecdsa.PrivateKey)
if !ok {
return errors.New("Private key type does not match public key type") }
if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 {
return errors.New("Private key does not match public key")
}
default:
return errors.New("Unknown public key algorithm")
} return nil
} // 检查证书的有效性通过certPool
func CheckCertAgainRoot(x509Cert *x509.Certificate, certPool *x509.CertPool) ([][]*x509.Certificate, error) {
opts := x509.VerifyOptions{
// TODO DNSName: "test.example.com",
Roots: certPool,
} return x509Cert.Verify(opts)
} // 对检查合格的密钥和CertPool传递证书
func CheckCertAgainstSKAndRoot(x509Cert *x509.Certificate, privateKey interface{}, certPool *x509.CertPool) error {
if err := CheckCertPKAgainstSK(x509Cert, privateKey); err != nil {
return err
} if _, err := CheckCertAgainRoot(x509Cert, certPool); err != nil {
return err
} return nil
}

conf

// 返回注冊ID
func (conf *NodeConfiguration) GetEnrollmentID() string {
key := "tests.crypto.users." + conf.Name + ".enrollid"
value := viper.GetString(key)
if value == "" {
panic(fmt.Errorf("Enrollment id not specified in configuration file. Please check that property '%s' is set", key))
}
return value
} //返回注冊password
func (conf *NodeConfiguration) GetEnrollmentPWD() string {
key := "tests.crypto.users." + conf.Name + ".enrollpw"
value := viper.GetString(key)
if value == "" {
panic(fmt.Errorf("Enrollment id not specified in configuration file. Please check that property '%s' is set", key))
}
return value
}

ecdsa

// 表示ECDSA签名
type ECDSASignature struct {
R, S *big.Int
} //生成一个新的ECDSA密钥
func NewECDSAKey() (*ecdsa.PrivateKey, error) {
return ecdsa.GenerateKey(conf.GetDefaultCurve(), rand.Reader)
} // ECDSASignDirect 符号
func ECDSASignDirect(signKey interface{}, msg []byte) (*big.Int, *big.Int, error) {
temp := signKey.(*ecdsa.PrivateKey)
h := Hash(msg)
r, s, err := ecdsa.Sign(rand.Reader, temp, h)
if err != nil {
return nil, nil, err
} return r, s, nil
} // ECDSASign 符号
func ECDSASign(signKey interface{}, msg []byte) ([]byte, error) {
temp := signKey.(*ecdsa.PrivateKey)
h := Hash(msg)
r, s, err := ecdsa.Sign(rand.Reader, temp, h)
if err != nil {
return nil, err
} // R, _ := r.MarshalText()
// S, _ := s.MarshalText()
//
// fmt.Printf("r [%s], s [%s]\n", R, S) raw, err := asn1.Marshal(ECDSASignature{r, s})
if err != nil {
return nil, err
} return raw, nil
} //校验
func ECDSAVerify(verKey interface{}, msg, signature []byte) (bool, error) {
ecdsaSignature := new(ECDSASignature)
_, err := asn1.Unmarshal(signature, ecdsaSignature)
if err != nil {
return false, nil
} // R, _ := ecdsaSignature.R.MarshalText()
// S, _ := ecdsaSignature.S.MarshalText()
// fmt.Printf("r [%s], s [%s]\n", R, S) temp := verKey.(*ecdsa.PublicKey)
h := Hash(msg)
return ecdsa.Verify(temp, h, ecdsaSignature.R, ecdsaSignature.S), nil
} // 測试签名功能
func VerifySignCapability(tempSK interface{}, certPK interface{}) error {
/* TODO: reactive or remove
msg := []byte("This is a message to be signed and verified by ECDSA!") sigma, err := ECDSASign(tempSK, msg)
if err != nil {
// log.Error("Error signing [%s].", err.Error()) return err
} ok, err := ECDSAVerify(certPK, msg, sigma)
if err != nil {
// log.Error("Error verifying [%s].", err.Error()) return err
} if !ok {
// log.Error("Signature not valid.") return errors.New("Signature not valid.")
} // log.Info("Verifing signature capability...done")
*/
return nil
}

hash

// 返回一个新的散列函数
func NewHash() hash.Hash {
return conf.GetDefaultHash()()
} // 散列使用提前定义散列函数的MSH
func Hash(msg []byte) []byte {
hash := NewHash()
hash.Write(msg)
return hash.Sum(nil)
} // hmacs x 使用密钥的密钥
func HMAC(key, x []byte) []byte {
mac := hmac.New(conf.GetDefaultHash(), key)
mac.Write(x) return mac.Sum(nil)
} // hmacs x 使用密钥的密钥,并截断
func HMACTruncated(key, x []byte, truncation int) []byte {
mac := hmac.New(conf.GetDefaultHash(), key)
mac.Write(x) return mac.Sum(nil)[:truncation]
}

io

// 检查一个文件夹是否丢失或为空
func DirMissingOrEmpty(path string) (bool, error) {
dirExists, err := DirExists(path)
if err != nil {
return false, err
}
if !dirExists {
return true, nil
} dirEmpty, err := DirEmpty(path)
if err != nil {
return false, err
}
if dirEmpty {
return true, nil
}
return false, nil
} // 检查一个文件夹是否存在
func DirExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
} // 检查一个文件夹是否为空
func DirEmpty(path string) (bool, error) {
f, err := os.Open(path)
if err != nil {
return false, err
}
defer f.Close() _, err = f.Readdir(1)
if err == io.EOF {
return true, nil
}
return false, err
} // 检查一个文件是否丢失
func FileMissing(path string, name string) (bool, error) {
_, err := os.Stat(filepath.Join(path, name))
if err != nil {
return true, err
}
return false, nil
} // 假设路径丢失返回true,否则返回false
func FilePathMissing(path string) (bool, error) {
_, err := os.Stat(path)
if err != nil {
return true, err
}
return false, nil
} // Base64解码
func DecodeBase64(in string) ([]byte, error) {
return base64.StdEncoding.DecodeString(in)
} // Base64编码
func EncodeBase64(in []byte) string {
return base64.StdEncoding.EncodeToString(in)
} //检查整数的阵列是否同样
func IntArrayEquals(a []int, b []int) bool {
if len(a) != len(b) {
return false
}
for i, v := range a {
if v != b[i] {
return false
}
}
return true
} // 检查 tcp端口是否打开
func IsTCPPortOpen(laddr string) error {
lis, err := net.Listen("tcp", laddr)
if err != nil {
return err
}
lis.Close()
return nil
} var seed uint32
var randmu sync.Mutex func reseed() uint32 {
return uint32(time.Now().UnixNano() + int64(os.Getpid()))
} func nextSuffix() string {
randmu.Lock()
r := seed
if r == 0 {
r = reseed()
}
r = r*1664525 + 1013904223 // constants from Numerical Recipes
seed = r
randmu.Unlock()
return strconv.Itoa(int(1e9 + r%1e9))[1:]
} // 返回一个暂时文件的路径与关于系统的暂时文件夹.
func TempFile(dir, prefix string) (name string, err error) {
if dir == "" {
dir = os.TempDir()
} nconflict := 0
for i := 0; i < 10000; i++ {
name = filepath.Join(dir, prefix+nextSuffix())
f, err := os.Stat(name)
if f != nil || os.IsExist(err) {
if nconflict++; nconflict > 10 {
randmu.Lock()
seed = reseed()
randmu.Unlock()
}
continue
}
break
}
return
}

math

// 返回x的绝对值
func Abs(x int) int {
if x < 0 {
return -x
}
return x
}

random

返回随机寻找的字节的长度

func GetRandomBytes(len int) ([]byte, error) {
key := make([]byte, len) _, err := rand.Read(key)
if err != nil {
return nil, err
} return key, nil
}

slice

// 通过切片克隆
func Clone(src []byte) []byte {
clone := make([]byte, len(src))
copy(clone, src) return clone
}

keys

// 为der反串行化为私钥
func PrivateKeyToDER(privateKey *ecdsa.PrivateKey) ([]byte, error) {
return x509.MarshalECPrivateKey(privateKey)
} // 将私钥转换为PEM
func PrivateKeyToPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
if len(pwd) != 0 {
return PrivateKeyToEncryptedPEM(privateKey, pwd)
} switch x := privateKey.(type) {
case *ecdsa.PrivateKey:
raw, err := x509.MarshalECPrivateKey(x) if err != nil {
return nil, err
} return pem.EncodeToMemory(
&pem.Block{
Type: "ECDSA PRIVATE KEY",
Bytes: raw,
},
), nil
default:
return nil, ErrInvalidKey
}
} // 将私钥转换为加密PEM
func PrivateKeyToEncryptedPEM(privateKey interface{}, pwd []byte) ([]byte, error) {
switch x := privateKey.(type) {
case *ecdsa.PrivateKey:
raw, err := x509.MarshalECPrivateKey(x) if err != nil {
return nil, err
} block, err := x509.EncryptPEMBlock(
rand.Reader,
"ECDSA PRIVATE KEY",
raw,
pwd,
x509.PEMCipherAES256) if err != nil {
return nil, err
} return pem.EncodeToMemory(block), nil default:
return nil, ErrInvalidKey
}
} // 将der串行化为私钥
func DERToPrivateKey(der []byte) (key interface{}, err error) {
//fmt.Printf("DER [%s]\n", EncodeBase64(der)) if key, err = x509.ParsePKCS1PrivateKey(der); err == nil {
return key, nil
}
//fmt.Printf("DERToPrivateKey Err [%s]\n", err)
if key, err = x509.ParsePKCS8PrivateKey(der); err == nil {
switch key.(type) {
case *rsa.PrivateKey, *ecdsa.PrivateKey:
return
default:
return nil, errors.New("Found unknown private key type in PKCS#8 wrapping")
}
}
//fmt.Printf("DERToPrivateKey Err [%s]\n", err)
if key, err = x509.ParseECPrivateKey(der); err == nil {
return
}
//fmt.Printf("DERToPrivateKey Err [%s]\n", err) return nil, errors.New("Failed to parse private key")
} // 将pem串行化为私钥
func PEMtoPrivateKey(raw []byte, pwd []byte) (interface{}, error) {
block, _ := pem.Decode(raw) // 从头部导出密钥的类型 if x509.IsEncryptedPEMBlock(block) {
if pwd == nil {
return nil, errors.New("Encrypted Key. Need a password!!!")
} decrypted, err := x509.DecryptPEMBlock(block, pwd)
if err != nil {
return nil, errors.New("Failed decryption!!!")
} key, err := DERToPrivateKey(decrypted)
if err != nil {
return nil, err
}
return key, err
} cert, err := DERToPrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return cert, err
} // 从PEM提取一个AES密钥
func PEMtoAES(raw []byte, pwd []byte) ([]byte, error) {
block, _ := pem.Decode(raw) if x509.IsEncryptedPEMBlock(block) {
if pwd == nil {
return nil, errors.New("Encrypted Key. Need a password!!!")
} decrypted, err := x509.DecryptPEMBlock(block, pwd)
if err != nil {
return nil, err
}
return decrypted, nil
} return block.Bytes, nil
} // 将AES封装为PEM格式
func AEStoPEM(raw []byte) []byte {
return pem.EncodeToMemory(&pem.Block{Type: "AES PRIVATE KEY", Bytes: raw})
} //将AES封装为加密PEM格式
func AEStoEncryptedPEM(raw []byte, pwd []byte) ([]byte, error) {
if len(pwd) == 0 {
return AEStoPEM(raw), nil
} block, err := x509.EncryptPEMBlock(
rand.Reader,
"AES PRIVATE KEY",
raw,
pwd,
x509.PEMCipherAES256) if err != nil {
return nil, err
} return pem.EncodeToMemory(block), nil
} // 将公钥反串行化为pem格式
func PublicKeyToPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
if len(pwd) != 0 {
return PublicKeyToEncryptedPEM(publicKey, pwd)
} switch x := publicKey.(type) {
case *ecdsa.PublicKey:
PubASN1, err := x509.MarshalPKIXPublicKey(x)
if err != nil {
return nil, err
} return pem.EncodeToMemory(
&pem.Block{
Type: "ECDSA PUBLIC KEY",
Bytes: PubASN1,
},
), nil default:
return nil, ErrInvalidKey
}
} // 将公钥转换为加密pem
func PublicKeyToEncryptedPEM(publicKey interface{}, pwd []byte) ([]byte, error) {
switch x := publicKey.(type) {
case *ecdsa.PublicKey:
raw, err := x509.MarshalPKIXPublicKey(x) if err != nil {
return nil, err
} block, err := x509.EncryptPEMBlock(
rand.Reader,
"ECDSA PUBLIC KEY",
raw,
pwd,
x509.PEMCipherAES256) if err != nil {
return nil, err
} return pem.EncodeToMemory(block), nil default:
return nil, ErrInvalidKey
}
} // 将pem串行化为公钥
func PEMtoPublicKey(raw []byte, pwd []byte) (interface{}, error) {
block, _ := pem.Decode(raw)
fmt.Printf("block % x\n", raw) if x509.IsEncryptedPEMBlock(block) {
if pwd == nil {
return nil, errors.New("Encrypted Key. Need a password!!!")
} decrypted, err := x509.DecryptPEMBlock(block, pwd)
if err != nil {
return nil, errors.New("Failed decryption!!!")
} key, err := DERToPublicKey(decrypted)
if err != nil {
return nil, err
}
return key, err
} cert, err := DERToPublicKey(block.Bytes)
if err != nil {
return nil, err
}
return cert, err
} //将der串行化为公钥
func DERToPublicKey(derBytes []byte) (pub interface{}, err error) {
key, err := x509.ParsePKIXPublicKey(derBytes) return key, err
}

IBM openblockchain学习(四)--crypto源代码分析的更多相关文章

  1. FFmpeg 结构体学习(四): AVFrame 分析

    在上文FFmpeg 结构体学习(三): AVPacket 分析我们学习了AVPacket结构体的相关内容.本文,我们将讲述一下AVFrame. AVFrame是包含码流参数较多的结构体.下面我们来分析 ...

  2. Volley简单学习使用五—— 源代码分析三

    一.Volley工作流程图: 二.Network     在NetworkDispatcher中须要处理的网络请求.由以下进行处理: NetworkResponse networkResponse = ...

  3. mybatis 学习四 源码分析 mybatis如何执行的一条sql

    总体三部分,创建sessionfactory,创建session,执行sql获取结果 1,创建sessionfactory      这里其实主要做的事情就是将xml的所有配置信息转换成一个Confi ...

  4. FFmpeg 结构体学习(五): AVCodec 分析

    在上文FFmpeg 结构体学习(四): AVFrame 分析我们学习了AVFrame结构体的相关内容.本文,我们将讲述一下AVCodec. AVCodec是存储编解码器信息的结构体.下面我们来分析一下 ...

  5. 新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t

    新秀nginx源代码分析数据结构篇(四)红黑树ngx_rbtree_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...

  6. Openstack本学习笔记——Neutron-server服务加载和启动源代码分析(三)

    本文是在学习Openstack过程中整理和总结.因为时间和个人能力有限.错误之处在所难免,欢迎指正! 在Neutron-server服务载入与启动源代码分析(二)中搞定模块功能的扩展和载入.我们就回到 ...

  7. Flume 1.7 源代码分析(四)从Source写数据到Channel

    Flume 1.7 源代码分析(一)源代码编译 Flume 1.7 源代码分析(二)总体架构 Flume 1.7 源代码分析(三)程序入口 Flume 1.7 源代码分析(四)从Source写数据到C ...

  8. 转:RTMPDump源代码分析

    0: 主要函数调用分析 rtmpdump 是一个用来处理 RTMP 流媒体的开源工具包,支持 rtmp://, rtmpt://, rtmpe://, rtmpte://, and rtmps://. ...

  9. MyBatis架构设计及源代码分析系列(一):MyBatis架构

    如果不太熟悉MyBatis使用的请先参见MyBatis官方文档,这对理解其架构设计和源码分析有很大好处. 一.概述 MyBatis并不是一个完整的ORM框架,其官方首页是这么介绍自己 The MyBa ...

随机推荐

  1. 性能优化之-------少用iframe

     1.DOM开销高 使用iframe的开销是很高的,在主页面中加载同等数量的div和iframe(标签内容都是空),iframe的耗时会比div的高1~2个数量级. 2.阻塞onload事件 在典型方 ...

  2. PostgreSQL 下生成 UUID(Guid)

    最近在Windows 10 下安装了 PostgreSQL(postgresql-9.6.3-1-windows.exe),在学习过程中,发现PostgreSQL 支持UUID(Guid)类型,但是却 ...

  3. C#执行PowserShell 脚本

    Windows PowserShell能够很简洁 快速通过Script脚本方式获得我们想要执行效果. 如何在C#中任意执行PowerShell脚本.?类似目前我要在做一个进程管理工具. 通过Power ...

  4. 《天书夜读:从汇编语言到windows内核编程》七 内核字符串与内存

    1)驱动中的字符串使用如下结构: typedef struct _UNICODE_STRING{ USHORT Length; //字符串的长度(字节数) USHORT MaximumLength; ...

  5. 设计模式的征途—9.组合(Composite)模式

    树形结构在软件中随处可见,比如操作系统中的目录结构,公司组织结构等等,如何运用面向对象的方式来处理这种树形结构是组合模式需要解决的问题.组合模式通过一种巧妙的设计方案来使得用户可以一致性地处理整个树形 ...

  6. DNS生效时间

    http://blog.itechol.com/space-33-do-blog-id-908.html http://www.madboa.com/geek/dig/ Dig简介 Dig是一个在类U ...

  7. 使用mysql5.7新特性(虚拟列)解决使用前通配符性能问题

    众所周知,在mysql里的后通配符可以使用索引查找,前通配查询却无法使用到索引,即使是使用到了索引,也是使用了索引全扫描,效率依然不高,再MySQL5.7之前,一直都没有好的办法解决,但是到了MySQ ...

  8. 【Win 10 应用开发】UI Composition 札记(八):用 XamlLight 制作灯光效果

    前面老周已介绍过灯光的使用,如果你忘了,请用九牛二虎之力猛点击这里去复习一下.本篇老周再介绍另一种添加灯光的方法,这种方法是专为 XAML 元素而设计的,可以很方便地为可视化元素添加灯光效果. 不知道 ...

  9. IIFE(立即执行函数表达式)

    我们经常会看到这样的写法: ;(fuction () { // do something })() 这就是一个简单的IIFE(立即执行函数表达式,immediately-invoked functio ...

  10. Java数据结构和算法(一)——简介

    本系列博客我们将学习数据结构和算法,为什么要学习数据结构和算法,这里我举个简单的例子. 编程好比是一辆汽车,而数据结构和算法是汽车内部的变速箱.一个开车的人不懂变速箱的原理也是能开车的,同理一个不懂数 ...