github.com/minio/console@v1.4.1/pkg/auth/utils/utils.go (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2021 MinIO, Inc. 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 package utils 18 19 import ( 20 "crypto/hmac" 21 "crypto/rand" 22 "crypto/sha256" 23 "encoding/base64" 24 "io" 25 "strings" 26 ) 27 28 // Do not use: 29 // https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go 30 // It relies on math/rand and therefore not on a cryptographically secure RNG => It must not be used 31 // for access/secret keys. 32 33 // The alphabet of random character string. Each character must be unique. 34 // 35 // The RandomCharString implementation requires that: 256 / len(letters) is a natural numbers. 36 // For example: 256 / 64 = 4. However, 5 > 256/62 > 4 and therefore we must not use a alphabet 37 // of 62 characters. 38 // The reason is that if 256 / len(letters) is not a natural number then certain characters become 39 // more likely then others. 40 const letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345" 41 42 func RandomCharString(n int) string { 43 random := make([]byte, n) 44 if _, err := io.ReadFull(rand.Reader, random); err != nil { 45 panic(err) // Can only happen if we would run out of entropy. 46 } 47 48 var s strings.Builder 49 for _, v := range random { 50 j := v % byte(len(letters)) 51 s.WriteByte(letters[j]) 52 } 53 return s.String() 54 } 55 56 func ComputeHmac256(message string, key []byte) string { 57 h := hmac.New(sha256.New, key) 58 h.Write([]byte(message)) 59 return base64.StdEncoding.EncodeToString(h.Sum(nil)) 60 }