ZBLOG

golang 编写 http AES 加密代理

下面是一个简单的 golang 编写的 http AES 加密代理示例代码:

  1. package main
  2. import (
  3. "crypto/aes"
  4. "crypto/cipher"
  5. "encoding/base64"
  6. "fmt"
  7. "io"
  8. "log"
  9. "net/http"
  10. "net/url"
  11. )
  12. const key = "1234567890123456" // 16字节的AES加密密钥
  13. func encrypt(text string) string {
  14. block, err := aes.NewCipher([]byte(key))
  15. if err != nil {
  16. panic(err)
  17. }
  18. plaintext := []byte(text)
  19. ciphertext := make([]byte, aes.BlockSize+len(plaintext))
  20. iv := ciphertext[:aes.BlockSize]
  21. if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  22. panic(err)
  23. }
  24. stream := cipher.NewCTR(block, iv)
  25. stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
  26. return base64.URLEncoding.EncodeToString(ciphertext)
  27. }
  28. func decrypt(text string) (string, error) {
  29. ciphertext, err := base64.URLEncoding.DecodeString(text)
  30. if err != nil {
  31. return "", err
  32. }
  33. block, err := aes.NewCipher([]byte(key))
  34. if err != nil {
  35. return "", err
  36. }
  37. if len(ciphertext) < aes.BlockSize {
  38. return "", fmt.Errorf("ciphertext too short")
  39. }
  40. iv := ciphertext[:aes.BlockSize]
  41. ciphertext = ciphertext[aes.BlockSize:]
  42. stream := cipher.NewCTR(block, iv)
  43. stream.XORKeyStream(ciphertext, ciphertext)
  44. return string(ciphertext), nil
  45. }
  46. func handleProxy(w http.ResponseWriter, r *http.Request) {
  47. targetUrl := r.URL.Query().Get("url")
  48. u, err := url.Parse(targetUrl)
  49. if err != nil {
  50. http.Error(w, err.Error(), http.StatusBadRequest)
  51. return
  52. }
  53. req, err := http.NewRequest(r.Method, u.String(), r.Body)
  54. if err != nil {
  55. http.Error(w, err.Error(), http.StatusBadRequest)
  56. return
  57. }
  58. resp, err := http.DefaultClient.Do(req)
  59. if err != nil {
  60. http.Error(w, err.Error(), http.StatusInternalServerError)
  61. return
  62. }
  63. defer resp.Body.Close()
  64. w.Header().Set("Content-Type", "application/json")
  65. io.Copy(w, resp.Body)
  66. }
  67. func handleEncryptProxy(w http.ResponseWriter, r *http.Request) {
  68. targetUrl := r.URL.Query().Get("url")
  69. u, err := url.Parse(targetUrl)
  70. if err != nil {
  71. http.Error(w, err.Error(), http.StatusBadRequest)
  72. return
  73. }
  74. req, err := http.NewRequest(r.Method, u.String(), r.Body)
  75. if err != nil {
  76. http.Error(w, err.Error(), http.StatusBadRequest)
  77. return
  78. }
  79. resp, err := http.DefaultClient.Do(req)
  80. if err != nil {
  81. http.Error(w, err.Error(), http.StatusInternalServerError)
  82. return
  83. }
  84. defer resp.Body.Close()
  85. w.Header().Set("Content-Type", "application/json")
  86. var encryptedBody string
  87. io.Copy(&encryptedBody, resp.Body)
  88. fmt.Fprintf(w, `{"data": "%s"}`, encrypt(encryptedBody))
  89. }
  90. func main() {
  91. http.HandleFunc("/proxy/", handleProxy)
  92. http.HandleFunc("/encrypt-proxy/", handleEncryptProxy)
  93. log.Fatal(http.ListenAndServe(":8080", nil))
  94. }

这段代码实现了两个路由:

  1. /proxy/ :直接代理访问目标地址,并返回原始响应内容。
  2. /encrypt-proxy/ :代理访问目标地址,加密响应内容后返回。

其中,AES 加密使用的是 CTR 模式。在 encrypt 函数中,先生成一个随机的 16 字节的初始向量(IV),再用 AES 加密算法对原始数据进行加密,并将 IV 和密文拼接成一个字节数组,并使用 base64 编码转换成字符串返回。在 decrypt 函数中,先将密文字符串解码为字节数组,然后从中提取出 IV 和密文部分,再用 AES 解密算法对密文进行解密,最后返回解密出来的明文字符串。

需要注意的是,由于原始的响应内容可能包含二进制数据,在将响应内容加密后,需要将加密后的字节数组转换成字符串类型返回给客户端。在 handleEncryptProxy 中,我使用了 fmt.Fprintf 来格式化输出 JSON 响应结果,但实际情况下,这种方式可能不太适合复杂的 JSON 结构,需要根据实际情况选择更适合的方式。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=1069

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?