From 99a38065bf10619a2677cb6dcbfe93ee16de69d1 Mon Sep 17 00:00:00 2001 From: zhangzengfei <zhangzengfei@iotlink.com> Date: 星期四, 21 十一月 2019 17:20:05 +0800 Subject: [PATCH] fix: encrypt replace with RSA --- machine.go | 87 ++++++ licence.go | 200 +++++++------ README.md | 51 +++ rsa.go | 485 ++++++++++++++++++++++++++++++++++ 4 files changed, 720 insertions(+), 103 deletions(-) diff --git a/README.md b/README.md index 159487d..4533534 100644 --- a/README.md +++ b/README.md @@ -7,20 +7,53 @@ "basic.com/valib/licence.git" ) -const key = "flzxsqc,ysyhljt." - func main() { + // 鐢熸垚绉橀挜鍜屽叕閽� + if len(os.Args) > 1 && os.Args[1] == "-g" { + licence.GetRsaKey() + return + } + // 鑾峰彇鏈哄櫒鐮� - machineCode := licence.GetMachineCode() + machCode := licence.GetMachineCode() + fmt.Println("MachineCode: ", machCode) - // 鐢熸垚Licence - licenceCode := licence.GenerateLicence(machineCode, "2019-12-12 00:00:00", key) + // 鑾峰彇娉ㄥ唽鐮�, 鍙傛暟: 鍏徃鍚�, 鐢靛瓙閭, 鎵嬫満鍙� + regCode := licence.GetRegisterCode("basic.com", "dev@basic.com", "13911697509") + fmt.Println("Register code:", regCode) - fmt.Println("machineCode: ", machineCode) - fmt.Println("licenceCode: ", licenceCode) + fd, err := os.Open("./private.key") + if err != nil { + fmt.Println(err) + return + } - // 楠岃瘉Licence锛� 0, 鎴愬姛 1, 鏃犳晥 2, 璁惧鏈巿鏉� 3, 杩囨湡 - fmt.Println(licence.VerifyLicence(licenceCode, key)) + defer fd.Close() + privateKey, err := ioutil.ReadAll(fd) + if err != nil { + fmt.Println(err) + return + } + + // 鐢熸垚Licence, 鍙傛暟: 娉ㄥ唽鐮�, 鍒版湡鏃堕棿, 绉橀挜 + licenceCode, err := licence.GenerateLicence(regCode, "2106-01-02 15:04:05", privateKey) + if err != nil { + fmt.Println("GenerateLicence error :", err) + return + } + fmt.Println("licence code:", licenceCode) + ioutil.WriteFile("./LicenceFile", []byte(licenceCode), 0666) + + // 瑙e瘑Licence鏂囦欢 + licenceText, err := licence.DecryptLicence("./LicenceFile", "./public.pem") + if err != nil { + fmt.Println("DecryptLicence error :", err) + return + } + fmt.Println("licence text:", string(licenceText)) + + // 楠岃瘉Licence, 鍙傛暟: LicenceFile, public.pem 鐨勮矾寰� 杩斿洖: 0, 鎴愬姛 1, 鏃犳晥 2, 璁惧鏈巿鏉� 3, 杩囨湡 + fmt.Println(licence.VerifyLicence("./LicenceFile", "./public.pem")) } ``` \ No newline at end of file diff --git a/licence.go b/licence.go index 14ed41c..31d5799 100644 --- a/licence.go +++ b/licence.go @@ -1,135 +1,147 @@ package licence import ( + "encoding/base64" "encoding/json" - "strings" + "io/ioutil" + "os" "time" - - "github.com/shirou/gopsutil/cpu" - "github.com/shirou/gopsutil/host" - psnet "github.com/shirou/gopsutil/net" - // "github.com/shirou/gopsutil/disk" ) -type Licence struct { +type RegisterCode struct { MachineCode string - Expires int64 + Company string + Email string + Phone string + Version string +} + +type Licence struct { + RegCode RegisterCode + Expires int64 + Timestamp int64 } const ( - ValidationErrorMalformed uint32 = iota + 1 // Licence is malformed - ValidationErrorUnverifiableHost // Licence could not be verified because of signing problems - ValidationErrorExpired // Signature validation failed + ValidationErrorDecrypt uint32 = iota + 1 // Licence is malformed + ValidationErrorUnverifiableHost // Host unauthorized + ValidationErrorExpired // Signature expired + ValidationErrorMalformed + + Version = "1.0.1" + aesKey = "www.aiotlink.com" ) -func GetMachineCode() string { - var machineCode string +func GetRegisterCode(company, email, phone string) string { + mCode := GetMachineCode() - // CPU - if cpu, err := cpu.Info(); err == nil { - for _, c := range cpu { - machineCode = strings.Join([]string{machineCode, c.String()}, "-cpu-") - } - } + regCode := RegisterCode{mCode, company, email, phone, Version} - // // Disk - // if diskInfo, err := disk.Partitions(false); err == nil { - // for _, d := range diskInfo { - // diskSerialNumber := disk.GetDiskSerialNumber(d.Device) - // strings.Join([]string{machineCode, diskSerialNumber}, "-") - // } - // } + json, _ := json.Marshal(regCode) - // Host - if host, err := host.Info(); err == nil { - machineCode = strings.Join([]string{machineCode, host.HostID}, "-host-") - } - - // Net - if net, err := psnet.Interfaces(); err == nil { - for _, n := range net { - if n.MTU == 1500 && !VNetFilter(&n) { - machineCode = strings.Join([]string{machineCode, n.HardwareAddr}, "-mac-") - } - } - } - - return GetMd5String(machineCode, true, false) + return AESEncodeStr(json, aesKey) } -func VNetFilter(iface *psnet.InterfaceStat) bool { - vNetNamePrefix := [...]string{ - "docker", - "br-", - "veth", - "Npcap", - "VirtualBox", - } - - vNetAddrPrefix := [...]string{ - "00:05:69", //vmware1 - "00:0C:29", //vmware2 - "00:50:56", //vmware3 - "00:1c:14", //vmware4 - "00:1C:42", //parallels1 - "00:03:FF", //microsoft virtual pc - "00:0F:4B", //virtual iron 4 - "00:16:3E", //red hat xen , oracle vm , xen source, novell xen - "08:00:27", //virtualbox - } - - if iface.HardwareAddr == "" { - return true - } - - for _, v := range vNetAddrPrefix { - if strings.HasPrefix(iface.HardwareAddr, v) { - return true - } - } - - for _, v := range vNetNamePrefix { - if strings.HasPrefix(iface.Name, v) { - return true - } - } - - return false +func DecryptRegisterCode(regCode string) []byte { + return AESDecodeStr(regCode, aesKey) } -func GenerateLicence(machineCode, timeOut, key string) string { +func GenerateLicence(regCode, timeOut string, privateKey []byte) (string, error) { timeLayout := "2006-01-02 15:04:05" //杞寲鎵�闇�妯℃澘 loc, _ := time.LoadLocation("Local") //鑾峰彇鏃跺尯 tmp, _ := time.ParseInLocation(timeLayout, timeOut, loc) - timestamp := tmp.Unix() + exp := tmp.Unix() + now := time.Now().Unix() - licence := Licence{machineCode, timestamp} + regCodeText := AESDecodeStr(regCode, aesKey) + var registerCode RegisterCode + if err := json.Unmarshal(regCodeText, ®isterCode); err != nil { + return "", err + } - json, _ := json.Marshal(licence) - return AESEncodeStr(json, key) + licence := Licence{registerCode, exp, now} + json, err := json.Marshal(licence) + if err != nil { + return "", err + } + + RSA := &RSASecurity{} + if err := RSA.SetPrivateKey(privateKey); err != nil { + return "", err + } + + licenceHex, err := RSA.PriKeyENCTYPT(json) + if err != nil { + return "", err + } + + licenceText := base64.StdEncoding.EncodeToString(licenceHex) + + return licenceText, nil } -func VerifyLicence(licenceCode, key string) uint32 { - decodeData := AESDecodeStr(licenceCode, key) - if decodeData == nil { - return ValidationErrorMalformed +func DecryptLicence(licencePath, publicKeyPath string) ([]byte, error) { + var publicKey, licenceCode []byte + var fdLic, fdPub *os.File + var err error + + // 璇诲彇Licence File + fdLic, err = os.Open(licencePath) + if err != nil { + return nil, err + } + defer fdLic.Close() + + licenceCode, err = ioutil.ReadAll(fdLic) + if err != nil { + return nil, err + } + + // 璇诲彇鍏挜 + fdPub, err = os.Open(publicKeyPath) + if err != nil { + return nil, err + } + defer fdPub.Close() + + publicKey, err = ioutil.ReadAll(fdPub) + if err != nil { + return nil, err + } + + RSA := &RSASecurity{} + if err := RSA.SetPublicKey(publicKey); err != nil { + return nil, err + } + + licenceHex, _ := base64.StdEncoding.DecodeString(string(licenceCode)) + + return RSA.PubKeyDECRYPT(licenceHex) +} + +func VerifyLicence(licencePath, publicKeyPath string) uint32 { + licenceText, err := DecryptLicence(licencePath, publicKeyPath) + if err != nil { + return ValidationErrorDecrypt } var licence Licence - if err := json.Unmarshal(decodeData, &licence); err != nil { + if err := json.Unmarshal(licenceText, &licence); err != nil { return ValidationErrorMalformed } - code := GetMachineCode() - if licence.MachineCode != code { - return ValidationErrorUnverifiableHost - } - + // 鍒ゆ柇杩囨湡 now := time.Now().Unix() if now > licence.Expires { return ValidationErrorExpired } + // 鍒ゆ柇鏈哄櫒鐮� + mCode := GetMachineCode() + if licence.RegCode.MachineCode != mCode { + return ValidationErrorUnverifiableHost + } + return 0 } diff --git a/machine.go b/machine.go new file mode 100644 index 0000000..82966df --- /dev/null +++ b/machine.go @@ -0,0 +1,87 @@ +package licence + +import ( + "strings" + + "github.com/shirou/gopsutil/cpu" + psnet "github.com/shirou/gopsutil/net" + // "github.com/shirou/gopsutil/host" + // "github.com/shirou/gopsutil/disk" +) + +func GetMachineCode() string { + var machineCode string + + // CPU + if cpu, err := cpu.Info(); err == nil { + for _, c := range cpu { + machineCode = strings.Join([]string{machineCode, c.String()}, "-cpu-") + } + } + + /* // Disk + if diskInfo, err := disk.Partitions(false); err == nil { + for _, d := range diskInfo { + diskSerialNumber := disk.GetDiskSerialNumber(d.Device) + strings.Join([]string{machineCode, diskSerialNumber}, "-") + } + } + + // Host + if host, err := host.Info(); err == nil { + machineCode = strings.Join([]string{machineCode, host.HostID}, "-host-") + }*/ + + // Net + if net, err := psnet.Interfaces(); err == nil { + for _, n := range net { + if n.MTU == 1500 && !VNetFilter(&n) { + machineCode = strings.Join([]string{machineCode, n.HardwareAddr}, "-mac-") + } + } + } + + return GetMd5String(machineCode, true, false) +} + +func VNetFilter(iface *psnet.InterfaceStat) bool { + if iface.HardwareAddr == "" { + return true + } + + vNetNamePrefix := [...]string{ + "docker", + "br-", + "veth", + "Npcap", + "VirtualBox", + } + + for _, v := range vNetNamePrefix { + if strings.HasPrefix(iface.Name, v) { + return true + } + } + + /* 鏆傛椂鏀惧純杩囨护铏氭嫙鏈篗AC锛屼細瀵艰嚧杩愯鍦ㄨ櫄鎷熸満鏃讹紝鏈哄櫒鐮佷笉鍖呭惈MAC鍦板潃鐨勯棶棰樸�傚鏋滀笉鍏佽鏈嶅姟杩愯鍦ㄨ櫄鎷熸満锛屽啀鍚敤骞舵彁绀鸿鍛� + vNetAddrPrefix := [...]string{ + "00:05:69", //vmware1 + "00:0C:29", //vmware2 + "00:50:56", //vmware3 + "00:1c:14", //vmware4 + "00:1C:42", //parallels1 + "00:03:FF", //microsoft virtual pc + "00:0F:4B", //virtual iron 4 + "00:16:3E", //red hat xen , oracle vm , xen source, novell xen + "08:00:27", //virtualbox + } + + for _, v := range vNetAddrPrefix { + if strings.HasPrefix(iface.HardwareAddr, v) { + return true + } + } + */ + + return false +} diff --git a/rsa.go b/rsa.go new file mode 100644 index 0000000..9391146 --- /dev/null +++ b/rsa.go @@ -0,0 +1,485 @@ +package licence + +import ( + "bytes" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "errors" + "io" + "io/ioutil" + "math/big" + "os" +) + +const ( + privateFileName = "private.key" + publicFileName = "public.pem" + + privateKeyPrefix = "BASIC AIOTLINK PRIVATE KEY " + publicKeyPrefix = "BASIC AIOTLINK PUBLIC KEY " +) + +type RSASecurity struct { + pubStr []byte //鍏挜瀛楃涓� + priStr []byte //绉侀挜瀛楃涓� + pubkey *rsa.PublicKey //鍏挜 + prikey *rsa.PrivateKey //绉侀挜 +} + +func GetRsaKey() error { + privateKey, err := rsa.GenerateKey(rand.Reader, 4096) + if err != nil { + return err + } + x509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey) + privateFile, err := os.Create(privateFileName) + if err != nil { + return err + } + defer privateFile.Close() + privateBlock := pem.Block{ + Type: privateKeyPrefix, + Bytes: x509PrivateKey, + } + + if err = pem.Encode(privateFile, &privateBlock); err != nil { + return err + } + publicKey := privateKey.PublicKey + x509PublicKey, err := x509.MarshalPKIXPublicKey(&publicKey) + if err != nil { + panic(err) + } + publicFile, _ := os.Create(publicFileName) + defer publicFile.Close() + publicBlock := pem.Block{ + Type: publicKeyPrefix, + Bytes: x509PublicKey, + } + if err = pem.Encode(publicFile, &publicBlock); err != nil { + return err + } + return nil +} + +// 璁剧疆鍏挜 +func (rsas *RSASecurity) SetPublicKey(pubStr []byte) (err error) { + rsas.pubStr = pubStr + rsas.pubkey, err = rsas.GetPublickey() + return err +} + +// 璁剧疆绉侀挜 +func (rsas *RSASecurity) SetPrivateKey(priStr []byte) (err error) { + rsas.priStr = priStr + rsas.prikey, err = rsas.GetPrivatekey() + return err +} + +// *rsa.PublicKey +func (rsas *RSASecurity) GetPrivatekey() (*rsa.PrivateKey, error) { + return getPriKey(rsas.priStr) +} + +// *rsa.PrivateKey +func (rsas *RSASecurity) GetPublickey() (*rsa.PublicKey, error) { + return getPubKey(rsas.pubStr) +} + +// 鍏挜鍔犲瘑 +func (rsas *RSASecurity) PubKeyENCTYPT(input []byte) ([]byte, error) { + if rsas.pubkey == nil { + return []byte(""), errors.New(`Please set the public key in advance`) + } + output := bytes.NewBuffer(nil) + err := pubKeyIO(rsas.pubkey, bytes.NewReader(input), output, true) + if err != nil { + return []byte(""), err + } + return ioutil.ReadAll(output) +} + +// 鍏挜瑙e瘑 +func (rsas *RSASecurity) PubKeyDECRYPT(input []byte) ([]byte, error) { + if rsas.pubkey == nil { + return []byte(""), errors.New(`Please set the public key in advance`) + } + output := bytes.NewBuffer(nil) + err := pubKeyIO(rsas.pubkey, bytes.NewReader(input), output, false) + if err != nil { + return []byte(""), err + } + return ioutil.ReadAll(output) +} + +// 绉侀挜鍔犲瘑 +func (rsas *RSASecurity) PriKeyENCTYPT(input []byte) ([]byte, error) { + if rsas.prikey == nil { + return []byte(""), errors.New(`Please set the private key in advance`) + } + output := bytes.NewBuffer(nil) + err := priKeyIO(rsas.prikey, bytes.NewReader(input), output, true) + if err != nil { + return []byte(""), err + } + return ioutil.ReadAll(output) +} + +// 绉侀挜瑙e瘑 +func (rsas *RSASecurity) PriKeyDECRYPT(input []byte) ([]byte, error) { + if rsas.prikey == nil { + return []byte(""), errors.New(`Please set the private key in advance`) + } + output := bytes.NewBuffer(nil) + err := priKeyIO(rsas.prikey, bytes.NewReader(input), output, false) + if err != nil { + return []byte(""), err + } + + return ioutil.ReadAll(output) +} + +var ( + ErrDataToLarge = errors.New("message too long for RSA public key size") + ErrDataLen = errors.New("data length error") + ErrDataBroken = errors.New("data broken, first byte is not zero") + ErrKeyPairDismatch = errors.New("data is not encrypted by the private key") + ErrDecryption = errors.New("decryption error") + ErrPublicKey = errors.New("get public key error") + ErrPrivateKey = errors.New("get private key error") +) + +// 璁剧疆鍏挜 +func getPubKey(publickey []byte) (*rsa.PublicKey, error) { + // decode public key + block, _ := pem.Decode(publickey) + if block == nil { + return nil, errors.New("get public key error") + } + // x509 parse public key + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, err + } + return pub.(*rsa.PublicKey), err +} + +// 璁剧疆绉侀挜 +func getPriKey(privatekey []byte) (*rsa.PrivateKey, error) { + block, _ := pem.Decode(privatekey) + if block == nil { + return nil, errors.New("get private key error") + } + pri, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err == nil { + return pri, nil + } + pri2, err := x509.ParsePKCS8PrivateKey(block.Bytes) + if err != nil { + return nil, err + } + return pri2.(*rsa.PrivateKey), nil +} + +// 鍏挜鍔犲瘑鎴栬В瀵哹yte +func pubKeyByte(pub *rsa.PublicKey, in []byte, isEncrytp bool) ([]byte, error) { + k := (pub.N.BitLen() + 7) / 8 + if isEncrytp { + k = k - 11 + } + if len(in) <= k { + if isEncrytp { + return rsa.EncryptPKCS1v15(rand.Reader, pub, in) + } else { + return pubKeyDecrypt(pub, in) + } + } else { + iv := make([]byte, k) + out := bytes.NewBuffer(iv) + if err := pubKeyIO(pub, bytes.NewReader(in), out, isEncrytp); err != nil { + return nil, err + } + return ioutil.ReadAll(out) + } +} + +// 绉侀挜鍔犲瘑鎴栬В瀵哹yte +func priKeyByte(pri *rsa.PrivateKey, in []byte, isEncrytp bool) ([]byte, error) { + k := (pri.N.BitLen() + 7) / 8 + if isEncrytp { + k = k - 11 + } + if len(in) <= k { + if isEncrytp { + return priKeyEncrypt(rand.Reader, pri, in) + } else { + return rsa.DecryptPKCS1v15(rand.Reader, pri, in) + } + } else { + iv := make([]byte, k) + out := bytes.NewBuffer(iv) + if err := priKeyIO(pri, bytes.NewReader(in), out, isEncrytp); err != nil { + return nil, err + } + return ioutil.ReadAll(out) + } +} + +// 鍏挜鍔犲瘑鎴栬В瀵哛eader +func pubKeyIO(pub *rsa.PublicKey, in io.Reader, out io.Writer, isEncrytp bool) (err error) { + k := (pub.N.BitLen() + 7) / 8 + if isEncrytp { + k = k - 11 + } + buf := make([]byte, k) + var b []byte + size := 0 + for { + size, err = in.Read(buf) + if err != nil { + if err == io.EOF { + return nil + } + return err + } + if size < k { + b = buf[:size] + } else { + b = buf + } + if isEncrytp { + b, err = rsa.EncryptPKCS1v15(rand.Reader, pub, b) + } else { + b, err = pubKeyDecrypt(pub, b) + } + if err != nil { + return err + } + if _, err = out.Write(b); err != nil { + return err + } + } + return nil +} + +// 绉侀挜鍔犲瘑鎴栬В瀵哛eader +func priKeyIO(pri *rsa.PrivateKey, r io.Reader, w io.Writer, isEncrytp bool) (err error) { + k := (pri.N.BitLen() + 7) / 8 + if isEncrytp { + k = k - 11 + } + buf := make([]byte, k) + var b []byte + size := 0 + for { + size, err = r.Read(buf) + if err != nil { + if err == io.EOF { + return nil + } + return err + } + if size < k { + b = buf[:size] + } else { + b = buf + } + if isEncrytp { + b, err = priKeyEncrypt(rand.Reader, pri, b) + } else { + b, err = rsa.DecryptPKCS1v15(rand.Reader, pri, b) + } + if err != nil { + return err + } + if _, err = w.Write(b); err != nil { + return err + } + } + return nil +} + +// 鍏挜瑙e瘑 +func pubKeyDecrypt(pub *rsa.PublicKey, data []byte) ([]byte, error) { + k := (pub.N.BitLen() + 7) / 8 + if k != len(data) { + return nil, ErrDataLen + } + m := new(big.Int).SetBytes(data) + if m.Cmp(pub.N) > 0 { + return nil, ErrDataToLarge + } + m.Exp(m, big.NewInt(int64(pub.E)), pub.N) + d := leftPad(m.Bytes(), k) + if d[0] != 0 { + return nil, ErrDataBroken + } + if d[1] != 0 && d[1] != 1 { + return nil, ErrKeyPairDismatch + } + var i = 2 + for ; i < len(d); i++ { + if d[i] == 0 { + break + } + } + i++ + if i == len(d) { + return nil, nil + } + return d[i:], nil +} + +// 绉侀挜鍔犲瘑 +func priKeyEncrypt(rand io.Reader, priv *rsa.PrivateKey, hashed []byte) ([]byte, error) { + tLen := len(hashed) + k := (priv.N.BitLen() + 7) / 8 + if k < tLen+11 { + return nil, ErrDataLen + } + em := make([]byte, k) + em[1] = 1 + for i := 2; i < k-tLen-1; i++ { + em[i] = 0xff + } + copy(em[k-tLen:k], hashed) + m := new(big.Int).SetBytes(em) + c, err := decrypt(rand, priv, m) + if err != nil { + return nil, err + } + copyWithLeftPad(em, c.Bytes()) + return em, nil +} + +// 浠巆rypto/rsa澶嶅埗 +var bigZero = big.NewInt(0) +var bigOne = big.NewInt(1) + +// 浠巆rypto/rsa澶嶅埗 +func encrypt(c *big.Int, pub *rsa.PublicKey, m *big.Int) *big.Int { + e := big.NewInt(int64(pub.E)) + c.Exp(m, e, pub.N) + return c +} + +// 浠巆rypto/rsa澶嶅埗 +func decrypt(random io.Reader, priv *rsa.PrivateKey, c *big.Int) (m *big.Int, err error) { + if c.Cmp(priv.N) > 0 { + err = ErrDecryption + return + } + var ir *big.Int + if random != nil { + var r *big.Int + + for { + r, err = rand.Int(random, priv.N) + if err != nil { + return + } + if r.Cmp(bigZero) == 0 { + r = bigOne + } + var ok bool + ir, ok = modInverse(r, priv.N) + if ok { + break + } + } + bigE := big.NewInt(int64(priv.E)) + rpowe := new(big.Int).Exp(r, bigE, priv.N) + cCopy := new(big.Int).Set(c) + cCopy.Mul(cCopy, rpowe) + cCopy.Mod(cCopy, priv.N) + c = cCopy + } + if priv.Precomputed.Dp == nil { + m = new(big.Int).Exp(c, priv.D, priv.N) + } else { + m = new(big.Int).Exp(c, priv.Precomputed.Dp, priv.Primes[0]) + m2 := new(big.Int).Exp(c, priv.Precomputed.Dq, priv.Primes[1]) + m.Sub(m, m2) + if m.Sign() < 0 { + m.Add(m, priv.Primes[0]) + } + m.Mul(m, priv.Precomputed.Qinv) + m.Mod(m, priv.Primes[0]) + m.Mul(m, priv.Primes[1]) + m.Add(m, m2) + + for i, values := range priv.Precomputed.CRTValues { + prime := priv.Primes[2+i] + m2.Exp(c, values.Exp, prime) + m2.Sub(m2, m) + m2.Mul(m2, values.Coeff) + m2.Mod(m2, prime) + if m2.Sign() < 0 { + m2.Add(m2, prime) + } + m2.Mul(m2, values.R) + m.Add(m, m2) + } + } + if ir != nil { + m.Mul(m, ir) + m.Mod(m, priv.N) + } + + return +} + +// 浠巆rypto/rsa澶嶅埗 +func copyWithLeftPad(dest, src []byte) { + numPaddingBytes := len(dest) - len(src) + for i := 0; i < numPaddingBytes; i++ { + dest[i] = 0 + } + copy(dest[numPaddingBytes:], src) +} + +// 浠巆rypto/rsa澶嶅埗 +func nonZeroRandomBytes(s []byte, rand io.Reader) (err error) { + _, err = io.ReadFull(rand, s) + if err != nil { + return + } + for i := 0; i < len(s); i++ { + for s[i] == 0 { + _, err = io.ReadFull(rand, s[i:i+1]) + if err != nil { + return + } + s[i] ^= 0x42 + } + } + return +} + +// 浠巆rypto/rsa澶嶅埗 +func leftPad(input []byte, size int) (out []byte) { + n := len(input) + if n > size { + n = size + } + out = make([]byte, size) + copy(out[len(out)-n:], input) + return +} + +// 浠巆rypto/rsa澶嶅埗 +func modInverse(a, n *big.Int) (ia *big.Int, ok bool) { + g := new(big.Int) + x := new(big.Int) + y := new(big.Int) + g.GCD(x, y, a, n) + if g.Cmp(bigOne) != 0 { + return + } + if x.Cmp(bigOne) < 0 { + x.Add(x, n) + } + return x, true +} -- Gitblit v1.8.0