소스 정보
- 저장소
- anybackup-ai/foundationCommon
- 최근 소스 활동
- 2026년 4월 30일 18:05
- 감지된 SKILL.md 언어
- 중국어
- 스타
- 2
- 포크
- 12
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/anybackup-ai/foundationCommon --skill frontend-param-encryption명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | frontend-param-encryption |
| description | 指导实现前端参数敏感信息RSA加密传输需求。当开发人员需要在后端接口解密前端加密的敏感参数(如密码)时调用此技能。 |
本技能指导如何在后端实现前端参数敏感信息(如密码)的RSA加密解密功能,确保敏感数据在HTTP传输过程中的安全性。
前端在调用后端接口时,需要对敏感参数(如密码)进行加密传输,后端接收后解密获取明文。这可以防止敏感信息在传输过程中被窃听。
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 加密传输流程 │
└─────────────────────────────────────────────────────────────────────────────────┘
前端 后端
┌─────────┐ ┌─────────┐
│ 明文密码 │ │ │
│ ↓ │ │ │
│ RSA公钥 │───── HTTP ─────────▶│ RSA私钥 │
│ 加密 │ 密文 │ 解密 │
│ ↓ │ │ ↓ │
│ 密文字符│ │ 明文密码 │
└─────────┘ └─────────┘
确保项目中已引入加密相关依赖。本实现基于 Flora/_git/greed/crypto 包:
import "github.com/anybackup-ai/Flora/_git/greed/crypto"
在 utils/ 目录下创建或修改加密相关文件,定义HTTP Header常量:
const (
MaskEncryptedHeader = "X-Mask-Encrypted" // 标识请求是否包含加密参数
MaskEncryptedValue = "true" // Header值为true表示需要解密
)
package utils
import (
"github.com/anybackup-ai/Flora/_git/greed/crypto"
"github.com/gin-gonic/gin"
)
// NewFrontendCryptoObj 创建前端加密解密对象
// 需要SSL私钥文件路径和私钥密码
func NewFrontendCryptoObj() (*crypto.FrontendCrypto, error) {
// 1. 加载SSL配置(从环境配置或配置文件获取)
sslConfig := loadSSLConfig()
// 2. 创建解密对象
cryptoObj, err := crypto.NewFrontendCrypto(
sslConfig.ServerKeyFile, // SSL私钥文件路径
[]byte(sslConfig.ServerCrtPwd), // 私钥密码
)
if err != nil {
return nil, err
}
return cryptoObj, nil
}
// FrontendDecrypt 解密前端传来的加密参数
// input: 加密后的字符串
// c: Gin上下文,用于获取HTTP Header
func FrontendDecrypt(input string, c *gin.Context) (string, error) {
// 1. 检查是否需要解密
maskEncrypted := c.GetHeader(MaskEncryptedHeader)
if maskEncrypted != MaskEncryptedValue {
return input, nil // 不需要解密,原样返回
}
// 2. 空值直接返回
if input == "" {
return "", nil
}
// 3. 创建解密对象并解密
cryptoObj, err := NewFrontendCryptoObj()
if err != nil {
return input, err
}
decryptedOutput, err := cryptoObj.Decrypt(input)
if err != nil {
return input, err
}
return string(decryptedOutput), nil
}
在处理注册/更新等涉及敏感参数的接口中调用解密函数:
func (h *VMwareHandler) Register(c *gin.Context, arg interface{}) error {
req, ok := arg.(*request.VmwareRegister)
if !ok {
return errors.New("type incorrect")
}
// 解密前端传来的加密密码
decryptedPassword, err := utils.FrontendDecrypt(req.Vmware.Password, c)
if err != nil {
return err
}
// 使用解密后的明文密码进行后续处理
// ...
}
请求参数中密码字段的长度限制需要考虑加密后的长度:
type VirtualPlatPassword struct {
// 加密后长度会增加,需要设置足够大的max值
Password string `json:"password" binding:"required,min=1,max=512"`
}
前端需要:
X-Mask-Encrypted: true// 前端示例(伪代码)
const encryptedPassword = RSA.encrypt(password, publicKey);
fetch('/api/virtual_platforms', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Mask-Encrypted': 'true' // 关键:告知后端需要解密
},
body: JSON.stringify({
password: encryptedPassword
})
});
SSL配置通常从环境配置中获取,包含以下字段:
| 字段 | 说明 |
|---|---|
| ServerKeyFile | 服务端私钥文件路径(用于解密) |
| ServerCrtFile | 服务端证书文件路径(包含公钥) |
| ServerCrtPwd | 私钥密码 |
| CAFile | CA证书文件路径 |
配置加载示例:
func loadSSLConfig() *SSLConfig {
config, err := hrc_core.GetEnvConfig()
if err != nil {
log.Error(err)
return nil
}
return config.ThriftSSLCfg
}
GET请求返回数据时,不要返回密码字段:
// 正确做法:响应结构体不包含密码
type VmwareGetCustme struct {
Version string `json:"version"`
Port int `json:"port"`
Username string `json:"username"` // 返回用户名
VerifiCation string `json:"verification"`
// 注意:没有 Password 字段
}
// 错误做法:返回密码(即使是加密的也不推荐)
type VmwareGetCustme struct {
Password string `json:"password"` // ❌ 不要这样做
}
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 两个独立的安全需求 │
└─────────────────────────────────────────────────────────────────────────────────┘
前端参数解密(传输安全) 密码存储加密(存储安全)
══════════════════════════ ══════════════════════════
前端 ──RSA加密──▶ HTTP ──▶ 后端解密 后端 ──KMC/AES──▶ 数据库
(防传输窃听) (防存储泄露)
解密后的明文密码如果需要存储,应使用KMC或AES等加密方式:
// 1. 先解密前端传来的加密密码
decryptedPassword, err := utils.FrontendDecrypt(req.Password, c)
// 2. 再用KMC加密存储(这是另一个独立的安全需求)
encryptedForStorage, err := utils.KMCEncrypt(decryptedPassword)
解密失败时应记录日志并返回适当错误:
decryptedPassword, err := utils.FrontendDecrypt(req.Password, c)
if err != nil {
global.GetLog().Errorf("frontend decrypt failed: %s", err)
return hrc_errors.New(errorCode.Common_ApplicationUnknownError,
map[string]string{"failReason": "Failed to decrypt password"})
}
utils/
├── frontendcrypto.go # 前端加密解密工具
├── crypt.go # 其他加密工具(KMC、AES等)
// utils/frontendcrypto.go
package utils
import (
"github.com/anybackup-ai/Flora/_git/greed/crypto"
"github.com/gin-gonic/gin"
)
const (
MaskEncryptedHeader = "X-Mask-Encrypted"
MaskEncryptedValue = "true"
)
func NewFrontendCryptoObj() (*crypto.FrontendCrypto, error) {
initials.LoadThriftSSLCfg()
cryptoObj, err := crypto.NewFrontendCrypto(
initials.ThriftSSLCfg.ServerKeyFile,
[]byte(initials.ThriftSSLCfg.ServerCrtPwd),
)
if err != nil {
global.GetLog().Errorf("NewFrontendCrypto error:%s", err)
return nil, err
}
return cryptoObj, nil
}
func FrontendDecrypt(input string, c *gin.Context) (string, error) {
maskEncrypted := c.GetHeader(MaskEncryptedHeader)
if maskEncrypted != MaskEncryptedValue {
return input, nil
}
if input == "" {
return "", nil
}
cryptoObj, err := NewFrontendCryptoObj()
if err != nil {
return input, err
}
decryptedOutput, err := cryptoObj.Decrypt(input)
if err != nil {
return input, err
}
return string(decryptedOutput),
}
| 场景 | 是否适用 |
|---|---|
| 用户密码传输 | ✅ 适用 |
| API密钥传输 | ✅ 适用 |
| 证书指纹传输 | ✅ 适用 |
| 大量数据加密 | ❌ 不适用(RSA不适合大数据) |
| 文件加密 | ❌ 不适用 |
RSA非对称加密的优势是前端只需要公钥,私钥只存在于后端,即使公钥泄露也无法解密。而AES对称加密需要前后端共享密钥,密钥管理更复杂。
RSA加密后的密文长度与密钥长度相关。通常1024位RSA加密后密文为172字节左右,2048位RSA加密后密文为344字节左右。建议密码字段max设置为512。
GET请求通常不涉及敏感参数传输。如果确实需要,GET请求的Query参数也可以使用相同的解密方式,但建议敏感参数通过POST请求体传输。