只是个示例,用户的数据在内存,后续扩展可以实现端对端加密
server
package mainimport ("crypto/aes""crypto/cipher""crypto/rand""crypto/rsa""crypto/sha256""crypto/x509""encoding/base64""encoding/pem""fmt""log""net/http""sync"
)// 用户密钥结构
type UserKey struct {UserID stringPublicKey stringPrivateKey *rsa.PrivateKeyUser string
}// 服务端密钥管理
type KeyManager struct {users map[string]*UserKeymutex sync.RWMutex
}func NewKeyManager() *KeyManager {return &KeyManager{users: make(map[string]*UserKey),}
}// 生成新的RSA密钥对
func (km *KeyManager) generateNewKeyPair() (*rsa.PrivateKey, error) {privateKey, err := rsa.GenerateKey(rand.Reader, 2048)if err != nil {return nil, fmt.Errorf("生成RSA密钥失败: %v", err)}return privateKey, nil
}// 保存或更新用户密钥
func (km *KeyManager) saveOrUpdateUserKey(userID, user string, privateKey *rsa.PrivateKey) error {// 序列化公钥publicKeyBytes, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)if err != nil {return fmt.Errorf("序列化公钥失败: %v", err)}pemPublicKey := pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY",Bytes: publicKeyBytes,})// 保存用户密钥信息km.mutex.Lock()defer km.mutex.Unlock()km.users[userID] = &UserKey{UserID: userID,PublicKey: string(pemPublicKey),PrivateKey: privateKey,User: user,}return nil
}// 根据用户ID获取私钥
func (km *KeyManager) getPrivateKeyByUserID(userID string) (*rsa.PrivateKey, error) {km.mutex.RLock()defer km.mutex.RUnlock()userKey, exists := km.users[userID]if !exists {return nil, fmt.Errorf("用户不存在: %s", userID)}return userKey.PrivateKey, nil
}// 根据用户ID获取公钥
func (km *KeyManager) getPublicKeyPEMByUserID(userID string) (string, error) {km.mutex.RLock()defer km.mutex.RUnlock()userKey, exists := km.users[userID]if !exists {return "", fmt.Errorf("用户不存在: %s", userID)}return userKey.PublicKey, nil
}// AES解密函数
func aesDecrypt(data, key []byte) ([]byte, error) {block, err := aes.NewCipher(key)if err != nil {return nil, err}gcm, err := cipher.NewGCM(block)if err != nil {return nil, err}nonceSize := gcm.NonceSize()if len(data) < nonceSize {return nil, fmt.Errorf("密文太短")}nonce, ciphertext := data[:nonceSize], data[nonceSize:]plaintext, err := gcm.Open(nil, nonce, ciphertext, nil)if err != nil {return nil, err}return plaintext, nil
}// RSA解密AES密钥
func (km *KeyManager) decryptAESKey(encryptedKeyStr string, userID string) ([]byte, error) {encryptedKey, err := base64.StdEncoding.DecodeString(encryptedKeyStr)if err != nil {return nil, fmt.Errorf("解码加密密钥失败: %v", err)}// 获取用户的私钥privateKey, err := km.getPrivateKeyByUserID(userID)if err != nil {return nil, fmt.Errorf("获取用户私钥失败: %v", err)}aesKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privateKey, encryptedKey, nil)if err != nil {return nil, fmt.Errorf("RSA解密密钥失败: %v", err)}return aesKey, nil
}// 服务端处理加密数据
func (km *KeyManager) decryptData(encryptedDataStr, encryptedKeyStr, userID string) (string, error) {// 解密AES密钥aesKey, err := km.decryptAESKey(encryptedKeyStr, userID)if err != nil {return "", err}// 解密数据encryptedData, err := base64.StdEncoding.DecodeString(encryptedDataStr)if err != nil {return "", fmt.Errorf("解码加密数据失败: %v", err)}decryptedData, err := aesDecrypt(encryptedData, aesKey)if err != nil {return "", fmt.Errorf("AES解密失败: %v", err)}return string(decryptedData), nil
}func main() {keyManager := NewKeyManager()// 启动HTTP服务器http.HandleFunc("/public-key", func(w http.ResponseWriter, r *http.Request) {if r.Method != http.MethodPost { // 使用POST方法接收登录信息http.Error(w, "只支持POST方法", http.StatusMethodNotAllowed)return}// 获取登录信息userID := r.FormValue("user_id")user := r.FormValue("user")password := r.FormValue("password")if userID == "" || user == "" || password == "" {http.Error(w, "缺少用户ID、用户名或密码", http.StatusBadRequest)return}// 简单密码验证if password != "123456" {http.Error(w, "密码错误", http.StatusUnauthorized)return}// 生成新的密钥对privateKey, err := keyManager.generateNewKeyPair()if err != nil {log.Printf("生成密钥对失败: %v", err)http.Error(w, fmt.Sprintf("生成密钥对失败: %v", err), http.StatusInternalServerError)return}// 保存或更新用户密钥err = keyManager.saveOrUpdateUserKey(userID, user, privateKey)if err != nil {log.Printf("保存用户密钥失败: %v", err)http.Error(w, fmt.Sprintf("保存用户密钥失败: %v", err), http.StatusInternalServerError)return}// 返回用户的公钥publicKeyPEM, err := keyManager.getPublicKeyPEMByUserID(userID)if err != nil {log.Printf("获取用户公钥失败: %v", err)http.Error(w, fmt.Sprintf("获取用户公钥失败: %v", err), http.StatusInternalServerError)return}w.Header().Set("Content-Type", "text/plain")fmt.Println("生成公钥", publicKeyPEM)fmt.Fprint(w, publicKeyPEM)})http.HandleFunc("/decrypt", func(w http.ResponseWriter, r *http.Request) {if r.Method != http.MethodPost {http.Error(w, "只支持POST方法", http.StatusMethodNotAllowed)return}// 从请求中获取加密数据、加密密钥和用户IDencryptedData := r.FormValue("data")encryptedKey := r.FormValue("key")userID := r.FormValue("user_id")fmt.Println("收到的请求数据", encryptedData, encryptedKey, userID)if encryptedData == "" || encryptedKey == "" || userID == "" {http.Error(w, "缺少加密数据、加密密钥或用户ID", http.StatusBadRequest)return}// 解密数据decryptedData, err := keyManager.decryptData(encryptedData, encryptedKey, userID)if err != nil {log.Printf("解密失败: %v", err)http.Error(w, fmt.Sprintf("解密失败: %v", err), http.StatusBadRequest)return}w.Header().Set("Content-Type", "text/plain")fmt.Println("解密数据", decryptedData)fmt.Fprint(w, decryptedData)})// 获取指定用户的公钥--端到端加密http.HandleFunc("/user-public-key", func(w http.ResponseWriter, r *http.Request) {if r.Method != http.MethodPost {http.Error(w, "只支持POST方法", http.StatusMethodNotAllowed)return}// 验证请求者身份--todorequesterID := r.FormValue("requester_id")requesterPassword := r.FormValue("requester_password")targetUserID := r.FormValue("target_user_id")if requesterID == "" || requesterPassword == "" || targetUserID == "" {http.Error(w, "缺少必要参数", http.StatusBadRequest)return}// 验证请求者身份(密码验证)if requesterPassword != "123456" { // 实际应用中应该使用更安全的验证方式http.Error(w, "身份验证失败", http.StatusUnauthorized)return}// 获取目标用户的公钥publicKeyPEM, err := keyManager.getPublicKeyPEMByUserID(targetUserID)if err != nil {log.Printf("获取用户公钥失败: %v", err)http.Error(w, fmt.Sprintf("获取用户公钥失败: %v", err), http.StatusInternalServerError)return}w.Header().Set("Content-Type", "text/plain")fmt.Fprint(w, publicKeyPEM)})fmt.Println("服务端启动在 :8080 端口")fmt.Printf("公钥获取地址: http://localhost:8080/public-key\n")fmt.Printf("解密接口地址: POST http://localhost:8080/decrypt\n")log.Fatal(http.ListenAndServe(":8080", nil))
}
client
package mainimport ("crypto/aes""crypto/cipher""crypto/rand""crypto/rsa""crypto/sha256""crypto/x509""encoding/base64""encoding/pem""fmt""io""net/http""net/url""strings"
)// AES加密函数
func aesEncrypt(data, key []byte) ([]byte, error) {block, err := aes.NewCipher(key)if err != nil {return nil, err}gcm, err := cipher.NewGCM(block)if err != nil {return nil, err}nonce := make([]byte, gcm.NonceSize())if _, err = io.ReadFull(rand.Reader, nonce); err != nil {return nil, err}ciphertext := gcm.Seal(nonce, nonce, data, nil)return ciphertext, nil
}// 从PEM格式加载公钥
func loadPublicKey(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
}// 使用服务端公钥进行混合加密
func hybridEncryptWithServerKey(plaintext string, serverPublicKeyPEM string) (string, string, error) {// 加载服务端公钥publicKey, err := loadPublicKey(serverPublicKeyPEM)if err != nil {return "", "", fmt.Errorf("加载公钥失败: %v", err)}// 生成AES密钥aesKey := make([]byte, 32) // 256位密钥if _, err := io.ReadFull(rand.Reader, aesKey); err != nil {return "", "", fmt.Errorf("生成AES密钥失败: %v", err)}// 使用AES加密数据encryptedData, err := aesEncrypt([]byte(plaintext), aesKey)if err != nil {return "", "", fmt.Errorf("AES加密失败: %v", err)}// 使用RSA公钥加密AES密钥encryptedKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, publicKey, aesKey, nil)if err != nil {return "", "", fmt.Errorf("RSA加密密钥失败: %v", err)}// 编码结果encodedData := base64.StdEncoding.EncodeToString(encryptedData)encodedKeyStr := base64.StdEncoding.EncodeToString(encryptedKey)return encodedData, encodedKeyStr, nil
}// 登录并从服务端获取公钥
func getServerPublicKey(serverURL, userID, user string) (string, error) {// 构建登录请求client := &http.Client{}formData := fmt.Sprintf("user_id=%s&user=%s&password=123456", url.QueryEscape(userID), url.QueryEscape(user))req, err := http.NewRequest("POST", serverURL+"/public-key", strings.NewReader(formData))if err != nil {return "", fmt.Errorf("创建登录请求失败: %v", err)}req.Header.Set("Content-Type", "application/x-www-form-urlencoded")resp, err := client.Do(req)if err != nil {return "", fmt.Errorf("发送登录请求失败: %v", err)}defer resp.Body.Close()if resp.StatusCode != http.StatusOK {return "", fmt.Errorf("登录失败,状态码: %d", resp.StatusCode)}publicKeyPEM := make([]byte, 2048) // 预分配更多空间n, err := resp.Body.Read(publicKeyPEM)if err != nil && err.Error() != "EOF" {return "", fmt.Errorf("读取公钥失败: %v", err)}return string(publicKeyPEM[:n]), nil
}// 向服务端发送加密数据并获取解密结果
func sendEncryptedData(serverURL, encryptedData, encryptedKey, userID string) (string, error) {// URL编码加密数据和密钥encodedData := url.QueryEscape(encryptedData)encodedKey := url.QueryEscape(encryptedKey)encodedUserID := url.QueryEscape(userID)client := &http.Client{}// 构建POST请求reqBody := fmt.Sprintf("data=%s&key=%s&user_id=%s", encodedData, encodedKey, encodedUserID)req, err := http.NewRequest("POST", serverURL+"/decrypt", strings.NewReader(reqBody))if err != nil {return "", fmt.Errorf("创建请求失败: %v", err)}req.Header.Set("Content-Type", "application/x-www-form-urlencoded")resp, err := client.Do(req)if err != nil {return "", fmt.Errorf("发送请求失败: %v", err)}defer resp.Body.Close()if resp.StatusCode != http.StatusOK {return "", fmt.Errorf("解密失败,状态码: %d", resp.StatusCode)}result := make([]byte, 1024) // 预分配空间n, err := resp.Body.Read(result)if err != nil && err.Error() != "EOF" {return "", fmt.Errorf("读取解密结果失败: %v", err)}return string(result[:n]), nil
}// 获取其他用户的公钥--端到端加密
func getTargetUserPublicKey(serverURL, requesterID, requesterPassword, targetUserID string) (string, error) {client := &http.Client{}formData := fmt.Sprintf("requester_id=%s&requester_password=%s&target_user_id=%s",url.QueryEscape(requesterID),url.QueryEscape(requesterPassword),url.QueryEscape(targetUserID))req, err := http.NewRequest("POST", serverURL+"/user-public-key", strings.NewReader(formData))if err != nil {return "", fmt.Errorf("创建请求失败: %v", err)}req.Header.Set("Content-Type", "application/x-www-form-urlencoded")resp, err := client.Do(req)if err != nil {return "", fmt.Errorf("发送请求失败: %v", err)}defer resp.Body.Close()if resp.StatusCode != http.StatusOK {return "", fmt.Errorf("获取公钥失败,状态码: %d", resp.StatusCode)}publicKeyPEM := make([]byte, 2048)n, err := resp.Body.Read(publicKeyPEM)if err != nil && err.Error() != "EOF" {return "", fmt.Errorf("读取公钥失败: %v", err)}return string(publicKeyPEM[:n]), nil
}func main() {serverURL := "http://localhost:8080"// 要加密的原始数据plaintext := "Hello, this is a secret message from client!"fmt.Printf("原始数据: %s\n", plaintext)// 从服务端获取公钥(模拟用户登录)userID := "user123" // 模拟用户IDuser := "john" // 模拟用户名fmt.Println("正在从服务端获取公钥...")publicKeyPEM, err := getServerPublicKey(serverURL, userID, user)if err != nil {fmt.Printf("获取公钥失败: %v\n", err)return}fmt.Printf("获取公钥成功\n")// 使用服务端公钥加密数据fmt.Println("正在使用服务端公钥加密数据...")encryptedData, encryptedKey, err := hybridEncryptWithServerKey(plaintext, publicKeyPEM)if err != nil {fmt.Printf("加密失败: %v\n", err)return}fmt.Printf("加密成功!\n")fmt.Printf("加密数据: %s\n", encryptedData)fmt.Printf("加密密钥: %s\n", encryptedKey)// 将加密数据发送到服务端进行解密fmt.Println("正在向服务端发送加密数据...")decryptedData, err := sendEncryptedData(serverURL, encryptedData, encryptedKey, userID)if err != nil {fmt.Printf("发送或解密失败: %v\n", err)return}fmt.Printf("服务端解密结果: %s\n", decryptedData)fmt.Println("混合加密通信演示完成!")
}

