github.com/blend/go-sdk@v1.20240719.1/crypto/create_key.go (about)

     1  /*
     2  
     3  Copyright (c) 2024 - Present. Blend Labs, Inc. All rights reserved
     4  Use of this source code is governed by a MIT license that can be found in the LICENSE file.
     5  
     6  */
     7  
     8  package crypto
     9  
    10  import (
    11  	cryptorand "crypto/rand"
    12  	"encoding/base64"
    13  	"encoding/binary"
    14  	"encoding/hex"
    15  
    16  	"github.com/blend/go-sdk/ex"
    17  )
    18  
    19  // MustCreateKey creates a key, if an error is returned, it panics.
    20  func MustCreateKey(keySize int) []byte {
    21  	key, err := CreateKey(keySize)
    22  	if err != nil {
    23  		panic(err)
    24  	}
    25  	return key
    26  }
    27  
    28  // CreateKey creates a key of a given size by reading that much data off the crypto/rand reader.
    29  func CreateKey(keySize int) ([]byte, error) {
    30  	key := make([]byte, keySize)
    31  	_, err := cryptorand.Read(key)
    32  	if err != nil {
    33  		return nil, err
    34  	}
    35  	return key, nil
    36  }
    37  
    38  // MustCreateKeyString generates a new key and returns it as a hex string.
    39  func MustCreateKeyString(keySize int) string {
    40  	return hex.EncodeToString(MustCreateKey(keySize))
    41  }
    42  
    43  // MustCreateKeyBase64String generates a new key and returns it as a base64 std encoding string.
    44  func MustCreateKeyBase64String(keySize int) string {
    45  	return base64.StdEncoding.EncodeToString(MustCreateKey(keySize))
    46  }
    47  
    48  // CreateKeyString generates a new key and returns it as a hex string.
    49  func CreateKeyString(keySize int) (string, error) {
    50  	key, err := CreateKey(keySize)
    51  	if err != nil {
    52  		return "", err
    53  	}
    54  	return hex.EncodeToString(key), nil
    55  }
    56  
    57  // CreateKeyBase64String generates a new key and returns it as a base64 std encoding string.
    58  func CreateKeyBase64String(keySize int) (string, error) {
    59  	key, err := CreateKey(keySize)
    60  	if err != nil {
    61  		return "", err
    62  	}
    63  	return base64.StdEncoding.EncodeToString(key), nil
    64  }
    65  
    66  // ParseKey parses a key from a string.
    67  func ParseKey(key string) ([]byte, error) {
    68  	decoded, err := hex.DecodeString(key)
    69  	if err != nil {
    70  		return nil, ex.New(err)
    71  	}
    72  	if len(decoded) != DefaultKeySize {
    73  		return nil, ex.New("parse key; invalid key length")
    74  	}
    75  	return decoded, nil
    76  }
    77  
    78  func formatNumToString(num uint64, digits int) string {
    79  	k := make([]byte, digits)
    80  	for i := digits - 1; i >= 0; i-- {
    81  		k[i] = byte(num%10 + '0')
    82  		num /= 10
    83  	}
    84  	return string(k)
    85  }
    86  
    87  // CreateIntKey creates an integer key of the specified length, return an error if it fails.
    88  func CreateIntKey(keySize int) (string, error) {
    89  
    90  	if keySize <= 0 {
    91  		return "", ex.New("parse key; invalid key length")
    92  	}
    93  
    94  	//take 8 bytes of randomness
    95  	key, err := CreateKey(8)
    96  	if err != nil {
    97  		return "", err
    98  	}
    99  	//convert random bytes to integer, then to string, limiting to keySize
   100  	intKey := binary.BigEndian.Uint64(key)
   101  	stringKey := formatNumToString(intKey, keySize)
   102  
   103  	return stringKey, nil
   104  }