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}