github.com/LanceLRQ/deer-common@v0.0.9-0.20210319081233-e8222ac018a8/persistence/utils.go (about) 1 package persistence 2 3 import ( 4 "bufio" 5 "bytes" 6 "crypto" 7 "crypto/rand" 8 "crypto/rsa" 9 "crypto/sha256" 10 "crypto/x509" 11 "encoding/pem" 12 "github.com/howeyc/gopass" 13 "github.com/pkg/errors" 14 uuid "github.com/satori/go.uuid" 15 "golang.org/x/crypto/openpgp" 16 "golang.org/x/crypto/openpgp/armor" 17 "io" 18 "io/ioutil" 19 "os" 20 "path" 21 ) 22 23 /* SHA256 */ 24 25 func SHA256String(body string) ([]byte, error) { 26 return SHA256Bytes([]byte(body)) 27 } 28 29 func SHA256Bytes(body []byte) ([]byte, error) { 30 buf := bytes.NewBuffer(body) 31 return SHA256Streams([]io.Reader{buf}) 32 } 33 34 func SHA256Streams(streams []io.Reader) ([]byte, error) { 35 hash := sha256.New() 36 for _, stream := range streams { 37 if _, err := io.Copy(hash, stream); err != nil { 38 return nil, err 39 } 40 } 41 ret := hash.Sum(nil) 42 //hex.EncodeToString(ret) 43 return ret, nil 44 } 45 46 /* RSA Sign */ 47 48 func RSA2048SignString(body string, privateKey *rsa.PrivateKey) ([]byte, error) { 49 return RSA2048SignBytes([]byte(body), privateKey) 50 } 51 52 func RSA2048SignBytes(body []byte, privateKey *rsa.PrivateKey) ([]byte, error) { 53 hash, err := SHA256Bytes(body) 54 if err != nil { 55 return nil, err 56 } 57 return RSA2048Sign(hash, privateKey) 58 } 59 60 func RSA2048Sign(hash []byte, privateKey *rsa.PrivateKey) ([]byte, error) { 61 sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, hash) 62 if err != nil { 63 return nil, err 64 } 65 return sign, nil 66 } 67 68 /* RSA Verify */ 69 70 func RSA2048VerifyString(body string, sign []byte, publicKey *rsa.PublicKey) error { 71 return RSA2048VerifyBytes([]byte(body), sign, publicKey) 72 } 73 74 func RSA2048VerifyBytes(body []byte, sign []byte, publicKey *rsa.PublicKey) error { 75 hash, err := SHA256Bytes(body) 76 if err != nil { 77 return err 78 } 79 return RSA2048Verify(hash, sign, publicKey) 80 } 81 82 func RSA2048Verify(hash []byte, sign []byte, publicKey *rsa.PublicKey) error { 83 return rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, hash, sign) 84 } 85 86 func ReadAndParsePublicKey(cert []byte) (*rsa.PublicKey, error) { 87 block, _ := pem.Decode(cert) 88 if block == nil { 89 return nil, errors.New("read public key error") 90 } 91 //publicKey, err := x509.ParseCertificate(block.Bytes) 92 publicKey, err := x509.ParsePKIXPublicKey(block.Bytes) 93 if err != nil { 94 return nil, err 95 } 96 return publicKey.(*rsa.PublicKey), nil 97 //return publicKey.PublicKey.(*rsa.PublicKey), nil 98 } 99 100 func ReadAndParsePrivateKey(key []byte) (*rsa.PrivateKey, error) { 101 block, _ := pem.Decode(key) 102 if block == nil { 103 return nil, errors.New("read private key error") 104 } 105 privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) 106 if err != nil { 107 return nil, err 108 } 109 return privateKey, nil 110 } 111 112 func ReadPemFile(filename string) ([]byte, error) { 113 pemBytes, err := ioutil.ReadFile(filename) 114 if err != nil { 115 return nil, err 116 } 117 return pemBytes, nil 118 } 119 120 func GetDigitalPEMFromFile(publicKeyFile string, privateKeyFile string) (*DigitalSignPEM, error) { 121 publicKey, err := ReadPemFile(publicKeyFile) 122 if err != nil { 123 return nil, err 124 } 125 privateKey, err := ReadPemFile(privateKeyFile) 126 if err != nil { 127 return nil, err 128 } 129 dp := GetDigitalPEM(publicKey, privateKey) 130 return dp, nil 131 } 132 133 func GetDigitalPEM(publicKey []byte, privateKey []byte) *DigitalSignPEM { 134 dp := DigitalSignPEM{} 135 if publicKey != nil { 136 dp.PublicKeyRaw = publicKey 137 pk, err := ReadAndParsePublicKey(publicKey) 138 dp.PublicKey = pk 139 if err != nil { 140 dp.PublicKey = nil 141 } 142 } 143 if privateKey != nil { 144 dp.PrivateKeyRaw = privateKey 145 pk, err := ReadAndParsePrivateKey(privateKey) 146 dp.PrivateKey = pk 147 if err != nil { 148 dp.PrivateKey = nil 149 } 150 } 151 return &dp 152 } 153 154 func Gets(reader io.Reader) string { 155 buf := make([]byte, 16, 16) 156 rd := bufio.NewReader(reader) 157 for { 158 t, err := rd.ReadByte() 159 if err != nil { 160 return string(buf) 161 } 162 buf = append(buf, t) 163 if t == 13 || t == 0 { 164 break 165 } 166 } 167 return string(buf) 168 } 169 170 func GetPublicKeyArmorBytes(entity *openpgp.Entity) ([]byte, error) { 171 pathname := path.Join("/tmp/" + uuid.NewV4().String() + ".key") 172 fp, err := os.Create(pathname) 173 if err != nil { 174 return nil, err 175 } 176 defer os.Remove(pathname) 177 178 w, err := armor.Encode(fp, openpgp.PublicKeyType, nil) 179 if err != nil { 180 return nil, err 181 } 182 err = entity.Serialize(w) 183 if err != nil { 184 return nil, err 185 } 186 _ = w.Close() 187 _ = fp.Close() 188 189 data, err := ioutil.ReadFile(pathname) 190 if err != nil { 191 return nil, err 192 } 193 return data, nil 194 } 195 196 func GetArmorPublicKey(gpgKeyFile string, passphrase []byte) (*DigitalSignPEM, error) { 197 if gpgKeyFile == "" { 198 return nil, errors.Errorf("please set GPG key file path") 199 } 200 // Open key 201 keyRingReader, err := os.Open(gpgKeyFile) 202 if err != nil { 203 return nil, err 204 } 205 // Read GPG Keys 206 elist, err := openpgp.ReadArmoredKeyRing(keyRingReader) 207 if err != nil { 208 return nil, err 209 } 210 if len(elist) < 1 { 211 return nil, errors.Errorf("file has no GPG key") 212 } 213 gpgKey := elist[0].PrivateKey 214 if gpgKey.Encrypted { 215 if len(passphrase) == 0 { 216 passphrase, err = gopass.GetPasswdPrompt("please input passphrase of key> ", true, os.Stdin, os.Stdout) 217 if err != nil { 218 return nil, err 219 } 220 } 221 err = gpgKey.Decrypt(passphrase) 222 if err != nil { 223 return nil, err 224 } 225 } 226 publicKeyArmor, err := GetPublicKeyArmorBytes(elist[0]) 227 if err != nil { 228 return nil, err 229 } 230 return &DigitalSignPEM{ 231 PrivateKey: gpgKey.PrivateKey.(*rsa.PrivateKey), 232 PublicKeyRaw: publicKeyArmor, 233 PublicKey: elist[0].PrimaryKey.PublicKey.(*rsa.PublicKey), 234 }, nil 235 }