博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IBM openblockchain学习(四)--crypto源代码分析
阅读量:5813 次
发布时间:2019-06-18

本文共 31543 字,大约阅读时间需要 105 分钟。

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}//生成非对称passwordfunc 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()}//从私钥创建非对称passwordfunc 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}//从公钥创建非对称passwordfunc 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)}//定义了一个非对称passwordtype 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转换为X509func DERToX509Certificate(asn1Data []byte) (*x509.Certificate, error) {    return x509.ParseCertificate(asn1Data)}//  将pem转换为X509func 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 转换为derfunc 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和derfunc 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转换为pemfunc 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}// 检查证书的有效性通过certPoolfunc 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

// 返回注冊IDfunc (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}//返回注冊passwordfunc (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()()}// 散列使用提前定义散列函数的MSHfunc 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,否则返回falsefunc 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 uint32var randmu sync.Mutexfunc 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)}// 将私钥转换为PEMfunc 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    }}// 将私钥转换为加密PEMfunc 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    }}// 将公钥转换为加密pemfunc 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}

转载地址:http://nmvbx.baihongyu.com/

你可能感兴趣的文章
如何通过Dataworks禁止MaxCompute 子账号跨Project访问
查看>>
js之无缝滚动
查看>>
17位女性科学家带你预测2017和2027
查看>>
Django 多表联合查询
查看>>
Freebsd系统故障导致系统不能正常启动的恢复数据方法[图]
查看>>
logging模块学习:basicConfig配置文件
查看>>
Golang 使用 Beego 与 Mgo 开发的示例程序
查看>>
DHCP服务器数据备份以及还原
查看>>
ntpdate时间同步
查看>>
Asp.Net MVC 插件化开发简化方案
查看>>
LH乱码转换
查看>>
+++++++子域授权与编译安装(一)
查看>>
编程修养(七)
查看>>
asp.net怎样在URL中使用中文、空格、特殊字符
查看>>
ISA2006实战系列之二:实战ISA三种客户端部署方案(下)
查看>>
Linux后门入侵检测工具,附bash漏洞最终解决方法
查看>>
ASA5585-S20测试方案
查看>>
利用for循环打印实心棱形和空心棱形
查看>>
路由器发布服务器
查看>>
实现跨交换机VLAN间的通信
查看>>