文章目录
  1. 1. elliptic
  2. 2. hash
  3. 3. init
  4. 4. generic
    1. 4.1. engine
      1. 4.1.1. aesEncrypt
      2. 4.1.2. aesDecrypt
      3. 4.1.3. eciesGenerateKey
      4. 4.1.4. eciesEncrypt
      5. 4.1.5. eciesDecrypt
    2. 4.2. es
    3. 4.3. kg
    4. 4.4. params
    5. 4.5. pk
    6. 4.6. sk
    7. 4.7. spi
  5. 5. crypto
  6. 6. aes
  7. 7. cert
  8. 8. conf
  9. 9. ecdsa
  10. 10. hash
  11. 11. io
  12. 12. math
  13. 13. random
  14. 14. slice
  15. 15. keys

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

elliptic

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

func GetDefaultCurve() elliptic.Curve {
return defaultCurve
}

hash

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

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

init

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

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
}
//生成非对称密码
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()
}
//从私钥创建非对称密码
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
}
//从公钥创建非对称密码
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
}

// 通用接口来表示密码参数
type CipherParameters interface {
Parameters
}

// 通用接口来表示非对称密码参数
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)
}

//定义了一个非对称密码
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 {

//从秘钥创建解密一个新的非对称密码
NewAsymmetricCipherFromPrivateKey(priv PrivateKey) (AsymmetricCipher, error)

//从公钥创建解密一个新的非对称密码
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
}

//返回注册密码
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
}
文章目录
  1. 1. elliptic
  2. 2. hash
  3. 3. init
  4. 4. generic
    1. 4.1. engine
      1. 4.1.1. aesEncrypt
      2. 4.1.2. aesDecrypt
      3. 4.1.3. eciesGenerateKey
      4. 4.1.4. eciesEncrypt
      5. 4.1.5. eciesDecrypt
    2. 4.2. es
    3. 4.3. kg
    4. 4.4. params
    5. 4.5. pk
    6. 4.6. sk
    7. 4.7. spi
  5. 5. crypto
  6. 6. aes
  7. 7. cert
  8. 8. conf
  9. 9. ecdsa
  10. 10. hash
  11. 11. io
  12. 12. math
  13. 13. random
  14. 14. slice
  15. 15. keys