简介
我提供了一种web通信加密方法,同时包括认证与签名的身份识别机制,完全通过我做过的小程序的token验证的经历和密码学课上数字签名与密码算法的学习所自己完成的。
主要面对web端与服务器之间的通信,例如最简单的情况,我们如何能向后台传输用户输入的隐秘信息,除了不被窃取以外还要保证身份可识别,不可伪造等多种重要的安全条件。一下我实现的通信加密以及验证机制可以比较好的避免以上所提到的安全情况,进而实现保密通信。在本次实验中我用模拟用户的密码输入登录的web端操作作为实例,演示如何实现安全通信的可识别身份的保密机制。
git地址:
点击前往
环境
我的开发测试环境:
硬件环境:
Dell 笔记本电脑
软件环境:
Windows10 操作系统
Goland IDE
WebStorm IDE
Chrome 浏览器
注:需要安装go的环境变量才能运行后端源码
运行要求:
Go的环境变量
连接外网
浏览器支持ES5
开发语言:
Go语言
Html,JavaScript,Css 等web前端语言
主要模块
内容:
(1)完成前端登录页面的设计与搭建
(2)建立go的web项目工程
(3)配置本地web环境,(端口,静态实例路径)
(4)绑定路由
(5)设计通信加密、签名、解密、验签流程图。
(6)完成相应算法的代码:
①go的服务器端:
1)AES加密、解密(这里实现的是CBC)
2)RSA加密、解密、生成密钥文件
3)Base64加密、解密
②前端页面js:
1)AES加密、解密(CBC)、生成密钥
2)RSA加密、解密
3)Base64加密
4)Md5加密
(7)按照通信流程图进行数据通信和模块连接
(8)测试
具体实现
- 完成前端登录页面的设计与搭建
具体代码在gitee上
- 建立go的web项目工程
- 配置本地web环境,(端口,静态实例路径)
1.//设置访问的路由
2. http.Handle("/resources/static/js/", http.StripPrefix("/resources/static/js/", http.FileServer(http.Dir("resources/static/js/"))))
3. http.HandleFunc("/", sayHelloName)
4. http.HandleFunc("/login", login)
5. http.HandleFunc("/upload", upload)
6. err := http.ListenAndServe(":9090",nil)
7. if err != nil {
8. log.Fatal("ListenAndServe:", err)
9. }
绑定路由:
- 设计通信加密、签名、解密、验签流程图
第一步:
第二步:
第三步:
第四步:
-
AES加密、解密(这里实现的是CBC)
-
RSA加密、解密、生成密钥文件
-
Base64解密
以上三个部分具体代码都在gitee上面,这里就不具体展开了。
- 前端处理流程代码
1.res, _ := ioutil.ReadAll(r.Body) //获取post的数据
2. str := string(res)
3. m := make(map[string]interface{})
4. err := json.Unmarshal([]byte(str), &m)
5. if err != nil {
6. fmt.Println("err=", err)
7. return
8. }
9. token := m["token"].(string)
10. Authorasation := m["Authoration"].(string)
11. SecurityKey := m["SecurityKey"].(string)
12. bodyStr := m["bodyStr"].(string)
13. timeStr := m["Timestamp"].(string)
14.
15. /* 判断时间戳 */
16. /* 如果超过某个规定时间就可以进行丢弃等操作 */
17. timeUnix:=time.Now().Unix()
18. fmt.Println("timestamp * 2:")
19. fmt.Println(timeUnix, timeStr)
20.
21.
22. /*利用RSA私钥从SecurityKey 中获取AESKey*/
23. b, err := base64.StdEncoding.DecodeString(SecurityKey)
24. AESKey_tmp := encryption.RSA_Decrypt(b,"private1.pem")
25. AESKey := string(AESKey_tmp)
26.
27. /* 利用AESKey解密获取bodystr */
28. decodeBytes1, err := base64.StdEncoding.DecodeString(AESKey)
29. tmp := string(decodeBytes1)
30. decodeBytes2, err := base64.StdEncoding.DecodeString(bodyStr)
31. bodystr_tmp := encryption.AesDecryptECB(decodeBytes2,[]byte(tmp));
32.
33. /* md5对bodystr生成摘要 */
34. md5Str := fmt.Sprintf("%x", md5.Sum(bodystr_tmp))
35. fmt.Println("md5Str:"+md5Str)
36.
37. /* 使用RSA密钥对authoration中的signature进行解密 */
38. b_tmp, err := base64.StdEncoding.DecodeString(Authorasation)
39. rsaDecryptoStr_tmp := encryption.RSA_Decrypt(b_tmp,"private1.pem")
40. rsaDecryptoStr := string(rsaDecryptoStr_tmp)
41. fmt.Println("rsaDecryptoStr:"+rsaDecryptoStr)
42.
43. /* 比较md5Str 和 rsaDecryptoStr*/
44.
45.
46.
47. if token != ""{
48. //验证合法性
49. fmt.Println("token:"+token)
50. }else{
51.
52. }
- 前端页面JS
AES:
RSA:
Base64加密
MD5加密:
- 结果
可见输出得到正确的结果,整个通信加密结构时正确的。
然后我又测了一下用时,
感觉不到停滞,是很流畅的 - 总结
在本次实验中,我是用RSA 、AES公钥加密算法,服务器拥有RSA的私钥并生成公钥发送给用户,成为加密的一个凭证。而用户也就是移动web端或生成AES的密钥,并利用RSA的公钥加密发送给服务器端,作为认证身份的一个凭证,也就是签名。然后在这主要的机制中又存在base64的摘要生成,长度规范同时便于管理,提高了整个系统的在HTTP环境下传递较长的标识信息的能力。同时md5的不可逆性很好的避免了用户绝对私密信息的暴露,同时它很强的唯一对应的特点也成为了服务器端对比校验的一个保证。