mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-11 18:35:51 +02:00
102 lines
2.4 KiB
Go
102 lines
2.4 KiB
Go
package crypto
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/0xJacky/Nginx-UI/internal/cache"
|
|
"github.com/uozi-tech/cosy/logger"
|
|
)
|
|
|
|
const (
|
|
CacheKey = "crypto"
|
|
timeout = 10 * time.Minute
|
|
)
|
|
|
|
type Params struct {
|
|
PrivateKey string `json:"-"`
|
|
PublicKey string `json:"public_key"`
|
|
}
|
|
|
|
// GenerateRSAKeyPair generates a new RSA key pair
|
|
func GenerateRSAKeyPair() (privateKeyPEM, publicKeyPEM []byte, err error) {
|
|
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
privateKeyPEM = pem.EncodeToMemory(&pem.Block{
|
|
Type: "RSA PRIVATE KEY",
|
|
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
|
|
})
|
|
publicKeyPEM = pem.EncodeToMemory(&pem.Block{
|
|
Type: "RSA PUBLIC KEY",
|
|
Bytes: x509.MarshalPKCS1PublicKey(&privateKey.PublicKey),
|
|
})
|
|
return
|
|
}
|
|
|
|
// GetCryptoParams registers a new key pair in the cache if it doesn't exist
|
|
// otherwise, it returns the existing nonce and public key
|
|
func GetCryptoParams() (params *Params, err error) {
|
|
// Check if the key pair exists in then cache
|
|
if value, ok := cache.Get(CacheKey); ok {
|
|
return value.(*Params), nil
|
|
}
|
|
// Generate a nonce = hash(publicKey)
|
|
privateKeyPEM, publicKeyPEM, err := GenerateRSAKeyPair()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
params = &Params{
|
|
PrivateKey: string(privateKeyPEM),
|
|
PublicKey: string(publicKeyPEM),
|
|
}
|
|
cache.Set(CacheKey, params, timeout)
|
|
return
|
|
}
|
|
|
|
// Decrypt decrypts the data with the private key (nonce, paramEncrypted)
|
|
func Decrypt(paramEncrypted string) (data map[string]interface{}, err error) {
|
|
// Get crypto params from cache
|
|
value, ok := cache.Get(CacheKey)
|
|
if !ok {
|
|
return nil, ErrTimeout
|
|
}
|
|
|
|
params := value.(*Params)
|
|
block, _ := pem.Decode([]byte(params.PrivateKey))
|
|
if block == nil {
|
|
return nil, fmt.Errorf("failed to decode PEM block containing private key")
|
|
}
|
|
|
|
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
|
if err != nil {
|
|
logger.Errorf("failed to parse private key: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
paramEncryptedDecoded, err := base64.StdEncoding.DecodeString(paramEncrypted)
|
|
if err != nil {
|
|
logger.Errorf("base64 decode error: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, paramEncryptedDecoded)
|
|
if err != nil {
|
|
logger.Errorf("decryption failed: %v", err)
|
|
return nil, err
|
|
}
|
|
|
|
err = json.Unmarshal(decrypted, &data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return
|
|
}
|