github.com/angenalZZZ/gofunc@v0.0.0-20210507121333-48ff1be3917b/f/crypto_key.go (about) 1 package f 2 3 import ( 4 "bytes" 5 "crypto/hmac" 6 "crypto/rsa" 7 "crypto/sha1" 8 "crypto/sha256" 9 "github.com/dgrijalva/jwt-go" 10 "hash" 11 ) 12 13 // CryptoSecretKeyPBKDF2WithHmacSHA1 derives key provided password, salt, iterations 1000, output 32 bytes. 14 func CryptoSecretKeyPBKDF2WithHmacSHA1(password, salt []byte, iterations, outLen int) []byte { 15 return CryptoSecretKeyPBKDF2WithHmac(sha1.New, password, salt, iterations, outLen) 16 } 17 18 // CryptoSecretKeyPBKDF2WithHmacSHA256 derives key provided password, salt, iterations 1000, output 32 bytes. 19 func CryptoSecretKeyPBKDF2WithHmacSHA256(password, salt []byte, iterations, outLen int) []byte { 20 return CryptoSecretKeyPBKDF2WithHmac(sha256.New, password, salt, iterations, outLen) 21 } 22 23 // CryptoSecretKeyPBKDF2WithHmac derives key of length outLen from the provided password, salt, 24 // and the number of iterations using PKCS#5 PBKDF2 with the provided hash function in HMAC. 25 // 26 // Caller is responsible to make sure that outLen < (2^32-1) * hash.Size(). 27 func CryptoSecretKeyPBKDF2WithHmac(hash func() hash.Hash, password, salt []byte, iterations, outLen int) []byte { 28 out := make([]byte, outLen) 29 hashSize := hash().Size() 30 buf := make([]byte, 4) 31 block := 1 32 p := out 33 for outLen > 0 { 34 clean := outLen 35 if clean > hashSize { 36 clean = hashSize 37 } 38 buf[0] = byte((block >> 24) & 0xff) 39 buf[1] = byte((block >> 16) & 0xff) 40 buf[2] = byte((block >> 8) & 0xff) 41 buf[3] = byte((block) & 0xff) 42 hmacPass := hmac.New(hash, password) 43 hmacPass.Write(salt) 44 hmacPass.Write(buf) 45 tmp := hmacPass.Sum(nil) 46 for i := 0; i < clean; i++ { 47 p[i] = tmp[i] 48 } 49 for j := 1; j < iterations; j++ { 50 hmacPass.Reset() 51 hmacPass.Write(tmp) 52 tmp = hmacPass.Sum(nil) 53 for k := 0; k < clean; k++ { 54 p[k] ^= tmp[k] 55 } 56 } 57 outLen -= clean 58 block++ 59 p = p[clean:] 60 } 61 return out 62 } 63 64 // CryptoPKCS5Padding for AES/CBC/PKCS5Padding 65 func CryptoPKCS5Padding(cipherText []byte, blockSize int) []byte { 66 padding := blockSize - len(cipherText)%blockSize 67 padText := bytes.Repeat([]byte{byte(padding)}, padding) 68 return append(cipherText, padText...) 69 } 70 71 // CryptoPKCS5UnPadding for AES/CBC/PKCS5UnPadding 72 func CryptoPKCS5UnPadding(origData []byte) []byte { 73 length := len(origData) 74 unPadding := int(origData[length-1]) 75 return origData[:(length - unPadding)] 76 } 77 78 //func pkcs7UnPadding(origData []byte, blockSize int) []byte { 79 // return origData[:len(origData)-int(origData[len(origData)-1])] 80 //} 81 82 // Parse PEM encoded PKCS1 or PKCS8 private key 83 func ParseRSAPrivateKeyFromPEM(key []byte) (*rsa.PrivateKey, error) { 84 return jwt.ParseRSAPrivateKeyFromPEM(key) 85 } 86 87 // Parse PEM encoded PKCS1 or PKCS8 private key protected with password 88 func ParseRSAPrivateKeyFromPEMWithPassword(key []byte, password string) (*rsa.PrivateKey, error) { 89 return jwt.ParseRSAPrivateKeyFromPEMWithPassword(key, password) 90 } 91 92 // Parse PEM encoded PKCS1 or PKCS8 public key 93 func ParseRSAPublicKeyFromPEM(key []byte) (*rsa.PublicKey, error) { 94 return jwt.ParseRSAPublicKeyFromPEM(key) 95 }