refactor: replace math/rand with crypto/rand for secure generation
- Updated `common.Random` and added `common.RandomInt` to use `crypto/rand` for cryptographically secure random number generation. - Added a thread-safe fallback to `math/rand` in case of system entropy failure. - Optimized `allSeq` initialization by using a rune slice literal instead of a loop in `init()`. - Refactored `util/outJson.go` to use the new `common.RandomInt`, removing the direct dependency on `math/rand`.
This commit is contained in:
+40
-15
@@ -1,30 +1,55 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
crand "crypto/rand"
|
||||||
|
"math/big"
|
||||||
|
mrand "math/rand"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
allSeq []rune
|
allSeq []rune = []rune{
|
||||||
rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
|
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||||
|
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||||
|
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||||
|
}
|
||||||
|
|
||||||
|
fallbackRand = mrand.New(mrand.NewSource(time.Now().UnixNano()))
|
||||||
|
fallbackMu = sync.Mutex{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
|
||||||
chars := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
|
||||||
for _, char := range chars {
|
|
||||||
allSeq = append(allSeq, char)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Random(n int) string {
|
func Random(n int) string {
|
||||||
runes := make([]rune, n)
|
if n <= 0 || len(allSeq) == 0 {
|
||||||
for i := 0; i < n; i++ {
|
return ""
|
||||||
runes[i] = allSeq[rnd.Intn(len(allSeq))]
|
|
||||||
}
|
}
|
||||||
return string(runes)
|
result := make([]rune, n)
|
||||||
|
maxBig := big.NewInt(int64(len(allSeq)))
|
||||||
|
for i := 0; i < n; i++ {
|
||||||
|
num, err := crand.Int(crand.Reader, maxBig)
|
||||||
|
if err != nil {
|
||||||
|
// fallback
|
||||||
|
fallbackMu.Lock()
|
||||||
|
result[i] = allSeq[fallbackRand.Intn(len(allSeq))]
|
||||||
|
fallbackMu.Unlock()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
result[i] = allSeq[int(num.Int64())]
|
||||||
|
}
|
||||||
|
return string(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RandomInt(n int) int {
|
func RandomInt(n int) int {
|
||||||
return rnd.Intn(n)
|
if n <= 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
max := big.NewInt(int64(n))
|
||||||
|
result, err := crand.Int(crand.Reader, max)
|
||||||
|
if err != nil {
|
||||||
|
// fallback
|
||||||
|
fallbackMu.Lock()
|
||||||
|
defer fallbackMu.Unlock()
|
||||||
|
return fallbackRand.Intn(n)
|
||||||
|
}
|
||||||
|
return int(result.Int64())
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -2,7 +2,8 @@ package util
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"math/rand"
|
|
||||||
|
"github.com/alireza0/s-ui/util/common"
|
||||||
|
|
||||||
"github.com/alireza0/s-ui/database/model"
|
"github.com/alireza0/s-ui/database/model"
|
||||||
)
|
)
|
||||||
@@ -108,7 +109,7 @@ func addTls(out *map[string]interface{}, tls *model.Tls) {
|
|||||||
realityConfig := tlsConfig["reality"].(map[string]interface{})
|
realityConfig := tlsConfig["reality"].(map[string]interface{})
|
||||||
realityConfig["enabled"] = true
|
realityConfig["enabled"] = true
|
||||||
if shortIDs, ok := reality["short_id"].([]interface{}); ok && len(shortIDs) > 0 {
|
if shortIDs, ok := reality["short_id"].([]interface{}); ok && len(shortIDs) > 0 {
|
||||||
realityConfig["short_id"] = shortIDs[rand.Intn(len(shortIDs))]
|
realityConfig["short_id"] = shortIDs[common.RandomInt(len(shortIDs))]
|
||||||
}
|
}
|
||||||
tlsConfig["reality"] = realityConfig
|
tlsConfig["reality"] = realityConfig
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user