zhangzengfei
2019-11-21 99a38065bf10619a2677cb6dcbfe93ee16de69d1
fix: encrypt replace with RSA
2个文件已添加
2个文件已修改
823 ■■■■ 已修改文件
README.md 51 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
licence.go 200 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
machine.go 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rsa.go 485 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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)
    // 解密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"))
}
```
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, &registerCode); 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
}
machine.go
New file
@@ -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
        }
    }
    /* 暂时放弃过滤虚拟机MAC,会导致运行在虚拟机时,机器码不包含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
}
rsa.go
New file
@@ -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)
}
// 公钥解密
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)
}
// 私钥解密
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
}
// 公钥加密或解密byte
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)
    }
}
// 私钥加密或解密byte
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)
    }
}
// 公钥加密或解密Reader
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
}
// 私钥加密或解密Reader
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
}
// 公钥解密
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
}
// 从crypto/rsa复制
var bigZero = big.NewInt(0)
var bigOne = big.NewInt(1)
// 从crypto/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
}
// 从crypto/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
}
// 从crypto/rsa复制
func copyWithLeftPad(dest, src []byte) {
    numPaddingBytes := len(dest) - len(src)
    for i := 0; i < numPaddingBytes; i++ {
        dest[i] = 0
    }
    copy(dest[numPaddingBytes:], src)
}
// 从crypto/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
}
// 从crypto/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
}
// 从crypto/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
}