diff --git a/controllers/admin/api.go b/controllers/admin/api.go index 65dbf71..0bc835d 100644 --- a/controllers/admin/api.go +++ b/controllers/admin/api.go @@ -10,10 +10,7 @@ import ( "strconv" "strings" "crypto/rand" - "crypto/rsa" - "crypto/x509" "encoding/hex" - "encoding/pem" "github.com/sirupsen/logrus" ) @@ -310,28 +307,51 @@ func APIGenerateKeysHandler(w http.ResponseWriter, r *http.Request) { result["private_key"] = "" case models.AlgorithmRC4: // 生成16字节随机密钥并返回16位十六进制(大写) - bytes := make([]byte, 8) - if _, err := rand.Read(bytes); err != nil { + key, err := encrypt.GenerateRC4Key(8) // 生成8字节密钥 + if err != nil { logrus.WithError(err).Error("Failed to generate RC4 key") http.Error(w, "生成RC4密钥失败", http.StatusInternalServerError) return } result["public_key"] = "" - result["private_key"] = strings.ToUpper(hex.EncodeToString(bytes)) - case models.AlgorithmRSA, models.AlgorithmRSADynamic: - // 生成RSA 2048密钥对,返回PEM明文字符串 - key, err := rsa.GenerateKey(rand.Reader, 2048) + result["private_key"] = strings.ToUpper(hex.EncodeToString(key)) + case models.AlgorithmRSA: + // 生成标准RSA 2048密钥对,返回PEM明文字符串 + publicKey, privateKey, err := encrypt.GenerateRSAKeyPair(2048) if err != nil { logrus.WithError(err).Error("Failed to generate RSA key pair") http.Error(w, "生成RSA密钥失败", http.StatusInternalServerError) return } - privBytes := x509.MarshalPKCS1PrivateKey(key) - pubBytes := x509.MarshalPKCS1PublicKey(&key.PublicKey) - privPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: privBytes}) - pubPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PUBLIC KEY", Bytes: pubBytes}) - result["private_key"] = string(privPEM) - result["public_key"] = string(pubPEM) + + // 转换为PEM格式 + publicKeyPEM, err := encrypt.PublicKeyToPEM(publicKey) + if err != nil { + logrus.WithError(err).Error("Failed to convert public key to PEM") + http.Error(w, "转换公钥格式失败", http.StatusInternalServerError) + return + } + + privateKeyPEM, err := encrypt.PrivateKeyToPEM(privateKey) + if err != nil { + logrus.WithError(err).Error("Failed to convert private key to PEM") + http.Error(w, "转换私钥格式失败", http.StatusInternalServerError) + return + } + + result["public_key"] = publicKeyPEM + result["private_key"] = privateKeyPEM + case models.AlgorithmRSADynamic: + // 生成RSA动态加密密钥对,返回PEM明文字符串 + publicKeyPEM, privateKeyPEM, err := encrypt.GenerateRSADynamicKeyPair(2048) + if err != nil { + logrus.WithError(err).Error("Failed to generate RSA dynamic key pair") + http.Error(w, "生成RSA动态密钥失败", http.StatusInternalServerError) + return + } + + result["public_key"] = publicKeyPEM + result["private_key"] = privateKeyPEM case models.AlgorithmEasy: // 生成易加密密钥对,返回逗号分隔的整数数组字符串 encryptKey, _, err := encrypt.GenerateEasyKey() diff --git a/utils/encrypt/rc4.go b/utils/encrypt/rc4.go new file mode 100644 index 0000000..d6519b3 --- /dev/null +++ b/utils/encrypt/rc4.go @@ -0,0 +1,112 @@ +package encrypt + +import ( + "crypto/rand" + "encoding/base64" + "fmt" +) + +// RC4Encrypt RC4加密算法结构体 +type RC4Encrypt struct { + key []byte +} + +// NewRC4Encrypt 创建新的RC4加密实例 +func NewRC4Encrypt(key []byte) *RC4Encrypt { + return &RC4Encrypt{ + key: key, + } +} + +// GenerateRC4Key 生成RC4密钥 +func GenerateRC4Key(length int) ([]byte, error) { + if length <= 0 || length > 256 { + length = 16 // 默认16字节密钥 + } + + key := make([]byte, length) + _, err := rand.Read(key) + if err != nil { + return nil, fmt.Errorf("生成RC4密钥失败: %v", err) + } + + return key, nil +} + +// rc4KeyScheduling RC4密钥调度算法(KSA) +func (r *RC4Encrypt) rc4KeyScheduling() []int { + s := make([]int, 256) + + // 初始化S盒 + for i := 0; i < 256; i++ { + s[i] = i + } + + // 密钥调度 + j := 0 + keyLen := len(r.key) + for i := 0; i < 256; i++ { + j = (j + s[i] + int(r.key[i%keyLen])) % 256 + s[i], s[j] = s[j], s[i] // 交换 + } + + return s +} + +// rc4PseudoRandomGeneration RC4伪随机生成算法(PRGA) +func (r *RC4Encrypt) rc4PseudoRandomGeneration(s []int, data []byte) []byte { + result := make([]byte, len(data)) + i, j := 0, 0 + + for k, b := range data { + i = (i + 1) % 256 + j = (j + s[i]) % 256 + s[i], s[j] = s[j], s[i] // 交换 + + keystream := s[(s[i]+s[j])%256] + result[k] = b ^ byte(keystream) + } + + return result +} + +// Encrypt RC4加密 +func (r *RC4Encrypt) Encrypt(plaintext string) (string, error) { + if len(r.key) == 0 { + return "", fmt.Errorf("RC4密钥不能为空") + } + + data := []byte(plaintext) + s := r.rc4KeyScheduling() + encrypted := r.rc4PseudoRandomGeneration(s, data) + + // Base64编码 + return base64.StdEncoding.EncodeToString(encrypted), nil +} + +// Decrypt RC4解密 +func (r *RC4Encrypt) Decrypt(ciphertext string) (string, error) { + if len(r.key) == 0 { + return "", fmt.Errorf("RC4密钥不能为空") + } + + // Base64解码 + data, err := base64.StdEncoding.DecodeString(ciphertext) + if err != nil { + return "", fmt.Errorf("Base64解码失败: %v", err) + } + + s := r.rc4KeyScheduling() + decrypted := r.rc4PseudoRandomGeneration(s, data) + + return string(decrypted), nil +} + +// ParseRC4KeyFromString 从字符串解析RC4密钥 +func ParseRC4KeyFromString(keyStr string) ([]byte, error) { + key, err := base64.StdEncoding.DecodeString(keyStr) + if err != nil { + return nil, fmt.Errorf("解析RC4密钥失败: %v", err) + } + return key, nil +} diff --git a/utils/encrypt/rsa.go b/utils/encrypt/rsa.go new file mode 100644 index 0000000..70f4030 --- /dev/null +++ b/utils/encrypt/rsa.go @@ -0,0 +1,105 @@ +package encrypt + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/pem" + "fmt" +) + +// GenerateRSAKeyPair 生成RSA密钥对(公共函数) +func GenerateRSAKeyPair(bits int) (*rsa.PublicKey, *rsa.PrivateKey, error) { + if bits < 1024 { + bits = 2048 // 默认2048位 + } + + privateKey, err := rsa.GenerateKey(rand.Reader, bits) + if err != nil { + return nil, nil, fmt.Errorf("生成RSA密钥对失败: %v", err) + } + + return &privateKey.PublicKey, privateKey, nil +} + +// PublicKeyToPEM 将RSA公钥转换为PEM格式字符串(公共函数) +func PublicKeyToPEM(publicKey *rsa.PublicKey) (string, error) { + publicKeyBytes, err := x509.MarshalPKIXPublicKey(publicKey) + if err != nil { + return "", fmt.Errorf("序列化公钥失败: %v", err) + } + + publicKeyPEM := pem.EncodeToMemory(&pem.Block{ + Type: "PUBLIC KEY", + Bytes: publicKeyBytes, + }) + + return string(publicKeyPEM), nil +} + +// PrivateKeyToPEM 将RSA私钥转换为PEM格式字符串(公共函数) +func PrivateKeyToPEM(privateKey *rsa.PrivateKey) (string, error) { + privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) + + privateKeyPEM := pem.EncodeToMemory(&pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: privateKeyBytes, + }) + + return string(privateKeyPEM), nil +} + +// PublicKeyFromPEM 从PEM格式字符串解析RSA公钥(公共函数) +func PublicKeyFromPEM(publicKeyPEM string) (*rsa.PublicKey, error) { + block, _ := pem.Decode([]byte(publicKeyPEM)) + if block == nil { + return nil, fmt.Errorf("无效的PEM格式公钥") + } + + publicKey, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return nil, fmt.Errorf("解析公钥失败: %v", err) + } + + rsaPublicKey, ok := publicKey.(*rsa.PublicKey) + if !ok { + return nil, fmt.Errorf("不是RSA公钥") + } + + return rsaPublicKey, nil +} + +// PrivateKeyFromPEM 从PEM格式字符串解析RSA私钥(公共函数) +func PrivateKeyFromPEM(privateKeyPEM string) (*rsa.PrivateKey, error) { + block, _ := pem.Decode([]byte(privateKeyPEM)) + if block == nil { + return nil, fmt.Errorf("无效的PEM格式私钥") + } + + privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + return nil, fmt.Errorf("解析私钥失败: %v", err) + } + + return privateKey, nil +} + +// GenerateRSAKeyPairPEM 生成RSA密钥对并返回PEM格式字符串(公共函数) +func GenerateRSAKeyPairPEM(bits int) (string, string, error) { + publicKey, privateKey, err := GenerateRSAKeyPair(bits) + if err != nil { + return "", "", err + } + + publicKeyPEM, err := PublicKeyToPEM(publicKey) + if err != nil { + return "", "", err + } + + privateKeyPEM, err := PrivateKeyToPEM(privateKey) + if err != nil { + return "", "", err + } + + return publicKeyPEM, privateKeyPEM, nil +} diff --git a/utils/encrypt/rsa_dynamic.go b/utils/encrypt/rsa_dynamic.go new file mode 100644 index 0000000..89effe3 --- /dev/null +++ b/utils/encrypt/rsa_dynamic.go @@ -0,0 +1,190 @@ +package encrypt + +import ( + "crypto/rand" + "crypto/rsa" + "encoding/base64" + "errors" + "fmt" +) + +// RSADynamicEncrypt RAS动态加密算法结构体 +type RSADynamicEncrypt struct { + publicKey *rsa.PublicKey + privateKey *rsa.PrivateKey +} + +// NewRSADynamicEncrypt 创建新的RAS动态加密实例 +func NewRSADynamicEncrypt(publicKeyPEM, privateKeyPEM string) (*RSADynamicEncrypt, error) { + var pubKey *rsa.PublicKey + var privKey *rsa.PrivateKey + var err error + + // 解析公钥 + if publicKeyPEM != "" { + pubKey, err = PublicKeyFromPEM(publicKeyPEM) // 使用公共函数 + if err != nil { + return nil, fmt.Errorf("failed to parse public key: %v", err) + } + } + + // 解析私钥 + if privateKeyPEM != "" { + privKey, err = PrivateKeyFromPEM(privateKeyPEM) // 使用公共函数 + if err != nil { + return nil, fmt.Errorf("failed to parse private key: %v", err) + } + } + + return &RSADynamicEncrypt{ + publicKey: pubKey, + privateKey: privKey, + }, nil +} + +// GenerateRSADynamicKeyPair 生成RSA动态加密密钥对 +func GenerateRSADynamicKeyPair(bits int) (string, string, error) { + return GenerateRSAKeyPairPEM(bits) // 使用公共函数 +} + +// generateDynamicKeys 生成动态密钥 +func generateDynamicKeys() ([]byte, error) { + // 生成3-6个随机密钥长度 + var lengthByte [1]byte + if _, err := rand.Read(lengthByte[:]); err != nil { + return nil, err + } + keyLen := 3 + int(lengthByte[0])%4 // 3-6个密钥 + + keys := make([]byte, keyLen) + for i := 0; i < keyLen; i++ { + var keyByte [1]byte + if _, err := rand.Read(keyByte[:]); err != nil { + return nil, err + } + // 确保密钥在1-255范围内 + keys[i] = keyByte[0] + if keys[i] == 0 { + keys[i] = 1 + } + } + + return keys, nil +} + +// xorEncrypt 使用动态密钥进行XOR加密 +func xorEncrypt(data []byte, keys []byte) []byte { + result := make([]byte, len(data)) + copy(result, data) + + for _, key := range keys { + for i := range result { + result[i] ^= key + } + } + + return result +} + +// xorDecrypt 使用动态密钥进行XOR解密(与加密相同) +func xorDecrypt(data []byte, keys []byte) []byte { + return xorEncrypt(data, keys) // XOR解密与加密相同 +} + +// Encrypt RAS动态加密 +func (r *RSADynamicEncrypt) Encrypt(plaintext string) (string, error) { + if r.publicKey == nil { + return "", errors.New("public key not set") + } + + // 1. 生成动态密钥 + dynamicKeys, err := generateDynamicKeys() + if err != nil { + return "", fmt.Errorf("failed to generate dynamic keys: %v", err) + } + + // 2. 使用动态密钥对明文进行XOR加密 + plaintextBytes := []byte(plaintext) + xorEncrypted := xorEncrypt(plaintextBytes, dynamicKeys) + + // 3. 构造最终数据:密钥长度 + 密钥 + 加密数据 + finalData := make([]byte, 0, 1+len(dynamicKeys)+len(xorEncrypted)) + finalData = append(finalData, byte(len(dynamicKeys))) // 密钥长度 + + // 按逆序插入密钥(与C++代码保持一致) + for i := len(dynamicKeys) - 1; i >= 0; i-- { + finalData = append(finalData, dynamicKeys[i]) + } + + finalData = append(finalData, xorEncrypted...) // 加密数据 + + // 4. 使用RSA公钥加密 + rsaEncrypted, err := rsa.EncryptPKCS1v15(rand.Reader, r.publicKey, finalData) + if err != nil { + return "", fmt.Errorf("RSA encryption failed: %v", err) + } + + // 5. Base64编码 + return base64.StdEncoding.EncodeToString(rsaEncrypted), nil +} + +// Decrypt RAS动态解密 +func (r *RSADynamicEncrypt) Decrypt(ciphertext string) (string, error) { + if r.privateKey == nil { + return "", errors.New("private key not set") + } + + // 1. Base64解码 + rsaEncrypted, err := base64.StdEncoding.DecodeString(ciphertext) + if err != nil { + return "", fmt.Errorf("base64 decode failed: %v", err) + } + + // 2. 使用RSA私钥解密 + decryptedData, err := rsa.DecryptPKCS1v15(rand.Reader, r.privateKey, rsaEncrypted) + if err != nil { + return "", fmt.Errorf("RSA decryption failed: %v", err) + } + + if len(decryptedData) < 1 { + return "", errors.New("decrypted data too short") + } + + // 3. 提取密钥长度 + keyLen := int(decryptedData[0]) + if len(decryptedData) < 1+keyLen { + return "", errors.New("invalid decrypted data format") + } + + // 4. 提取动态密钥(按逆序存储的) + dynamicKeys := make([]byte, keyLen) + for i := 0; i < keyLen; i++ { + dynamicKeys[keyLen-1-i] = decryptedData[1+i] // 恢复原始顺序 + } + + // 5. 提取XOR加密的数据 + xorEncryptedData := decryptedData[1+keyLen:] + + // 6. 使用动态密钥进行XOR解密 + plaintext := xorDecrypt(xorEncryptedData, dynamicKeys) + + return string(plaintext), nil +} + +// EncryptWithKeys 使用指定的公钥进行RAS动态加密 +func EncryptWithKeys(plaintext, publicKeyPEM string) (string, error) { + rsaEncrypt, err := NewRSADynamicEncrypt(publicKeyPEM, "") + if err != nil { + return "", err + } + return rsaEncrypt.Encrypt(plaintext) +} + +// DecryptWithKeys 使用指定的私钥进行RAS动态解密 +func DecryptWithKeys(ciphertext, privateKeyPEM string) (string, error) { + rsaEncrypt, err := NewRSADynamicEncrypt("", privateKeyPEM) + if err != nil { + return "", err + } + return rsaEncrypt.Decrypt(ciphertext) +} diff --git a/utils/encrypt/rsa_standard.go b/utils/encrypt/rsa_standard.go new file mode 100644 index 0000000..74d487c --- /dev/null +++ b/utils/encrypt/rsa_standard.go @@ -0,0 +1,124 @@ +package encrypt + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha256" + "encoding/base64" + "fmt" +) + +// RSAEncrypt 普通RSA加密算法结构体 +type RSAEncrypt struct { + publicKey *rsa.PublicKey + privateKey *rsa.PrivateKey +} + +// NewRSAEncrypt 创建新的RSA加密实例 +func NewRSAEncrypt(publicKey *rsa.PublicKey, privateKey *rsa.PrivateKey) *RSAEncrypt { + return &RSAEncrypt{ + publicKey: publicKey, + privateKey: privateKey, + } +} + +// Encrypt RSA公钥加密 +func (r *RSAEncrypt) Encrypt(plaintext string) (string, error) { + if r.publicKey == nil { + return "", fmt.Errorf("RSA公钥不能为空") + } + + data := []byte(plaintext) + + // 使用OAEP填充进行加密 + encrypted, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, r.publicKey, data, nil) + if err != nil { + return "", fmt.Errorf("RSA加密失败: %v", err) + } + + // Base64编码 + return base64.StdEncoding.EncodeToString(encrypted), nil +} + +// Decrypt RSA私钥解密 +func (r *RSAEncrypt) Decrypt(ciphertext string) (string, error) { + if r.privateKey == nil { + return "", fmt.Errorf("RSA私钥不能为空") + } + + // Base64解码 + data, err := base64.StdEncoding.DecodeString(ciphertext) + if err != nil { + return "", fmt.Errorf("Base64解码失败: %v", err) + } + + // 使用OAEP填充进行解密 + decrypted, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, r.privateKey, data, nil) + if err != nil { + return "", fmt.Errorf("RSA解密失败: %v", err) + } + + return string(decrypted), nil +} + +// EncryptLargeData RSA分块加密大数据 +func (r *RSAEncrypt) EncryptLargeData(plaintext string) (string, error) { + if r.publicKey == nil { + return "", fmt.Errorf("RSA公钥不能为空") + } + + data := []byte(plaintext) + keySize := r.publicKey.Size() + blockSize := keySize - 2*sha256.Size - 2 // OAEP填充的最大明文长度 + + var encrypted []byte + + for i := 0; i < len(data); i += blockSize { + end := i + blockSize + if end > len(data) { + end = len(data) + } + + block := data[i:end] + encryptedBlock, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, r.publicKey, block, nil) + if err != nil { + return "", fmt.Errorf("RSA分块加密失败: %v", err) + } + + encrypted = append(encrypted, encryptedBlock...) + } + + return base64.StdEncoding.EncodeToString(encrypted), nil +} + +// DecryptLargeData RSA分块解密大数据 +func (r *RSAEncrypt) DecryptLargeData(ciphertext string) (string, error) { + if r.privateKey == nil { + return "", fmt.Errorf("RSA私钥不能为空") + } + + data, err := base64.StdEncoding.DecodeString(ciphertext) + if err != nil { + return "", fmt.Errorf("Base64解码失败: %v", err) + } + + keySize := r.privateKey.Size() + var decrypted []byte + + for i := 0; i < len(data); i += keySize { + end := i + keySize + if end > len(data) { + end = len(data) + } + + block := data[i:end] + decryptedBlock, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, r.privateKey, block, nil) + if err != nil { + return "", fmt.Errorf("RSA分块解密失败: %v", err) + } + + decrypted = append(decrypted, decryptedBlock...) + } + + return string(decrypted), nil +} diff --git a/web/template/admin/apis.html b/web/template/admin/apis.html index 7349141..317dc8d 100644 --- a/web/template/admin/apis.html +++ b/web/template/admin/apis.html @@ -19,7 +19,7 @@
- +
@@ -38,7 +38,7 @@