github.com/sohaha/zlsgo@v1.7.13-0.20240501141223-10dd1a906f76/zstring/ras.go (about) 1 package zstring 2 3 import ( 4 "bytes" 5 "crypto" 6 "crypto/rand" 7 "crypto/rsa" 8 "crypto/x509" 9 "encoding/pem" 10 "errors" 11 "fmt" 12 "math/big" 13 ) 14 15 // GenRSAKey RSA public key private key generation 16 func GenRSAKey(bits ...int) (prvkey, pubkey []byte, err error) { 17 l := 1024 18 if len(bits) > 0 { 19 l = bits[0] 20 } 21 privateKey, err := rsa.GenerateKey(rand.Reader, l) 22 if err != nil { 23 return nil, nil, err 24 } 25 derStream := x509.MarshalPKCS1PrivateKey(privateKey) 26 block := &pem.Block{ 27 Type: "RSA PRIVATE KEY", 28 Bytes: derStream, 29 } 30 prvkey = pem.EncodeToMemory(block) 31 publicKey := &privateKey.PublicKey 32 derPkix, err := x509.MarshalPKIXPublicKey(publicKey) 33 if err != nil { 34 return nil, nil, err 35 } 36 block = &pem.Block{ 37 Type: "PUBLIC KEY", 38 Bytes: derPkix, 39 } 40 pubkey = pem.EncodeToMemory(block) 41 return 42 } 43 44 // RSAEncrypt RSA Encrypt 45 func RSAEncrypt(plainText []byte, publicKey string, bits ...int) ([]byte, error) { 46 pub, err := pubKey(String2Bytes(publicKey)) 47 if err != nil { 48 return nil, err 49 } 50 return RSAKeyEncrypt(plainText, pub, bits...) 51 } 52 53 // RSAKeyEncrypt RSA Encrypt 54 func RSAKeyEncrypt(plainText []byte, publicKey *rsa.PublicKey, bits ...int) ([]byte, error) { 55 if len(bits) > 0 && bits[0] > 100 { 56 buf := splitBytes(plainText, bits[0]/8-11) 57 buffer := bytes.NewBufferString("") 58 for i := range buf { 59 b, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, buf[i]) 60 if err != nil { 61 return nil, err 62 } 63 buffer.Write(b) 64 } 65 return Base64Encode(buffer.Bytes()), nil 66 } 67 cipherText, err := rsa.EncryptPKCS1v15(rand.Reader, publicKey, plainText) 68 if err != nil { 69 return nil, err 70 } 71 return Base64Encode(cipherText), nil 72 } 73 74 // RSAEncryptString RSA Encrypt to String 75 func RSAEncryptString(plainText string, publicKey string) (string, error) { 76 c, err := RSAEncrypt(String2Bytes(plainText), publicKey) 77 if err != nil { 78 return "", err 79 } 80 return Bytes2String(c), nil 81 } 82 83 // RSAPriKeyEncrypt RSA PriKey Encrypt 84 func RSAPriKeyEncrypt(plainText []byte, privateKey string) ([]byte, error) { 85 prv, err := priKey(String2Bytes(privateKey)) 86 if err != nil { 87 return nil, err 88 } 89 cipherText, err := rsa.SignPKCS1v15(nil, prv, crypto.Hash(0), plainText) 90 if err != nil { 91 return nil, err 92 } 93 return Base64Encode(cipherText), nil 94 } 95 96 // RSAPriKeyEncryptString RSA PriKey Encrypt to String 97 func RSAPriKeyEncryptString(plainText string, privateKey string) (string, error) { 98 c, err := RSAPriKeyEncrypt(String2Bytes(plainText), privateKey) 99 if err != nil { 100 return "", err 101 } 102 return Bytes2String(c), nil 103 } 104 105 // RSADecrypt RSA Decrypt 106 func RSADecrypt(cipherText []byte, privateKey string, bits ...int) ([]byte, error) { 107 prv, err := priKey(String2Bytes(privateKey)) 108 if err != nil { 109 return nil, err 110 } 111 return RSAKeyDecrypt(cipherText, prv, bits...) 112 } 113 114 // RSAKeyDecrypt RSA Decrypt 115 func RSAKeyDecrypt(cipherText []byte, privateKey *rsa.PrivateKey, bits ...int) ([]byte, error) { 116 cipherText, _ = Base64Decode(cipherText) 117 if len(bits) > 0 && bits[0] > 100 { 118 buf := splitBytes(cipherText, bits[0]/8) 119 buffer := bytes.NewBufferString("") 120 for i := range buf { 121 b, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, buf[i]) 122 if err != nil { 123 return nil, err 124 } 125 buffer.Write(b) 126 } 127 return buffer.Bytes(), nil 128 } 129 return rsa.DecryptPKCS1v15(rand.Reader, privateKey, cipherText) 130 } 131 132 // RSADecryptString RSA Decrypt to String 133 func RSADecryptString(cipherText string, privateKey string) (string, error) { 134 p, err := RSADecrypt(String2Bytes(cipherText), privateKey) 135 if err != nil { 136 return "", err 137 } 138 return Bytes2String(p), nil 139 } 140 141 // RSAPubKeyDecrypt RSA PubKey Decrypt 142 func RSAPubKeyDecrypt(cipherText []byte, publicKey string) ([]byte, error) { 143 pub, err := pubKey(String2Bytes(publicKey)) 144 if err != nil { 145 return nil, err 146 } 147 tLen := 0 148 k := (pub.N.BitLen() + 7) / 8 149 if k < tLen+11 { 150 return nil, fmt.Errorf("length illegal") 151 } 152 cipherText, _ = Base64Decode(cipherText) 153 c := new(big.Int).SetBytes(cipherText) 154 e := big.NewInt(int64(pub.E)) 155 m := c.Exp(c, e, pub.N) 156 em := leftPad(m.Bytes(), k) 157 return unLeftPad(em), nil 158 } 159 160 // RSAPubKeyDecryptString RSA PubKey Decrypt to String 161 func RSAPubKeyDecryptString(cipherText string, publicKey string) (string, 162 error) { 163 p, err := RSAPubKeyDecrypt(String2Bytes(cipherText), publicKey) 164 if err != nil { 165 return "", err 166 } 167 return Bytes2String(p), nil 168 } 169 170 func pubKey(publicKey []byte) (*rsa.PublicKey, error) { 171 block, _ := pem.Decode(publicKey) 172 if block == nil { 173 return nil, errors.New("public key is illegal") 174 } 175 publicKeyInterface, err := x509.ParsePKIXPublicKey(block.Bytes) 176 if err != nil { 177 return nil, err 178 } 179 pub, _ := publicKeyInterface.(*rsa.PublicKey) 180 return pub, nil 181 } 182 183 func priKey(privateKey []byte) (*rsa.PrivateKey, error) { 184 block, _ := pem.Decode(privateKey) 185 if block == nil { 186 return nil, errors.New("private key is illegal") 187 } 188 189 switch block.Type { 190 case "PRIVATE KEY": 191 // pkcs8 192 parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes) 193 if err == nil { 194 parsed, ok := parsedKey.(*rsa.PrivateKey) 195 if !ok { 196 return nil, errors.New("private key is invalid") 197 } 198 return parsed, nil 199 } 200 return nil, err 201 default: 202 return x509.ParsePKCS1PrivateKey(block.Bytes) 203 } 204 } 205 206 func leftPad(input []byte, size int) (out []byte) { 207 n := len(input) 208 if n > size { 209 n = size 210 } 211 out = make([]byte, size) 212 copy(out[len(out)-n:], input) 213 return 214 } 215 216 func unLeftPad(input []byte) (out []byte) { 217 n := len(input) 218 t := 2 219 for i := 2; i < n; i++ { 220 if input[i] == 0xff { 221 t = t + 1 222 } else { 223 if input[i] == input[0] { 224 t = t + int(input[1]) 225 } 226 break 227 } 228 } 229 out = make([]byte, n-t) 230 copy(out, input[t:]) 231 return 232 } 233 234 func splitBytes(buf []byte, lim int) [][]byte { 235 var chunk []byte 236 chunks := make([][]byte, 0, len(buf)/lim+1) 237 for len(buf) >= lim { 238 chunk, buf = buf[:lim], buf[lim:] 239 chunks = append(chunks, chunk) 240 } 241 if len(buf) > 0 { 242 chunks = append(chunks, buf[:]) 243 } 244 return chunks 245 }