github.com/treeverse/lakefs@v1.24.1-0.20240520134607-95648127bfb0/pkg/auth/keys/keys.go (about)

     1  package keys
     2  
     3  import (
     4  	crand "crypto/rand"
     5  	"encoding/base64"
     6  	"encoding/hex"
     7  	"fmt"
     8  	"strings"
     9  )
    10  
    11  const AkiaAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567" // Amazon AKIA alphabet is weird.
    12  
    13  func KeyGenerator(length int) string {
    14  	var b strings.Builder
    15  
    16  	for {
    17  		bbuf := make([]byte, length) // one byte of randomness per character isn't really needed but it makes the implementation simpler
    18  		_, err := crand.Read(bbuf)
    19  		if err != nil {
    20  			continue // let's retry until we have enough entropy
    21  		}
    22  		for i := 0; i < length; i++ {
    23  			c := bbuf[i]
    24  			b.WriteByte(AkiaAlphabet[int(c)%len(AkiaAlphabet)])
    25  		}
    26  		break
    27  	}
    28  	return b.String()
    29  }
    30  
    31  func Base64StringGenerator(bytes int) string {
    32  	var ret string
    33  	bbuf := make([]byte, bytes)
    34  	for {
    35  		_, err := crand.Read(bbuf)
    36  		if err != nil {
    37  			continue
    38  		}
    39  		ret = base64.StdEncoding.EncodeToString(bbuf)
    40  		break
    41  	}
    42  	return ret
    43  }
    44  
    45  func HexStringGenerator(bytes int) string {
    46  	var ret string
    47  	buf := make([]byte, bytes)
    48  	for {
    49  		_, err := crand.Read(buf)
    50  		if err != nil {
    51  			continue
    52  		}
    53  		ret = strings.ToUpper(hex.EncodeToString(buf))
    54  		break
    55  	}
    56  	return ret
    57  }
    58  
    59  func GenAccessKeyID() string {
    60  	const accessKeyLength = 14
    61  	key := KeyGenerator(accessKeyLength)
    62  	return fmt.Sprintf("%s%s%s", "AKIAJ", key, "Q")
    63  }
    64  
    65  func GenSecretAccessKey() string {
    66  	const secretKeyLength = 30
    67  	return Base64StringGenerator(secretKeyLength)
    68  }