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 }