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  }