前言

  接上版,本次版本做了如下优化:

  1、新增同意、拒绝添加好友后做线上提示;

  2、新增好友分组,使用工具生成后台API,新增好友分组功能,主要功能有:添加分组、重命名分组名称、删除分组

  3、新增好友管理,主要功能:删除好友(下个版本再实现功能)、移动好友至其他分组

  4、添加好友时有验证信息、好友备注、好友分组 

  5、AIP接口、WebSocket通道的前后端交互采用AES与RSA混合加密,防抓包监听,加、解密操作后并不影响业务,AIP接口、WebSocket通道的前后端交互正常

  优化细节

  1、新增同意、拒绝添加好友后做线上提示;

  

  2、新增好友分组,使用工具生成后台API,新增好友分组功能,主要功能有:添加分组、重命名分组名称、删除分组

  没有分组的默认在列表前面追加,分组名称后面展示对应好友数以及在线好友数量

  添加分组、重命名分组名称、删除分组

  

  3、新增好友管理,主要功能:删除好友(下个版本再实现功能)、移动好友至其他分组

  移动好友至其他分组

  4、添加好友时有验证信息、好友备注、好友分组

  先登录两个还不是好友的人,各种新增一个好友分组

 

  A向B发起好友申请

  同意好友申请

  拒绝好友申请

  5、AIP接口、WebSocket通道的前后端交互采用AES与RSA混合加密,防抓包监听,加、解密操作后并不影响业务,AIP接口、WebSocket通道的前后端交互正常

  API交互,关于前后端API安全交互,我前段时间实现了一套AES与RSA混合加密,详情请戳:前后端API交互数据加密——AES与RSA混合加密完整实例

  WebSocket聊天,webSocket的加、解密与AIP的加、解密原理一样,发送前加密、收到数据后解密再交给业务处理,有个地方要注意的是,我们在进行消息转发时,要用的是接收方的前端公钥进行加密

  建立WebSocket连接时,将当前用户的前端公钥发送到后端,后端进行Map保存(只贴出关键代码)

    //因为是url的方式传值,公钥中的/需要进行转换一下,传到后端再转回来(PS:因为生成的公钥里是不存在","的,所以这里转成逗号)websocket = new WebSocket("ws://localhost:10086/websocket/" + userId + "/" + window.jsPublicKey.replace(/\//g,","));

/*** WebSocket服务*/
@Component
@ServerEndpoint(value = "/websocket/{userId}/{publicKey}", configurator = MyEndpointConfigure.class)
public class WebSocketServer {//省略其他代码  /*** 登录用户的前端公钥Map集合(其实应该放在Redis)*/private static Map<Session, String> loginPublicKeyList = new HashMap<Session, String>();/*** 连接建立成功调用的方法*/@OnOpenpublic void onOpen(Session session, @PathParam("userId") String userId, @PathParam("publicKey") String publicKey) {//省略其他代码//设置前端公钥,因为是url的方式传值,公钥中的/需要进行转换一下,传到后端再转回来,然后将每个用户的前端公钥存储起来loginPublicKeyList.put(session,publicKey.replaceAll(",", "/"));}
}

  前端发送前加密

//发送消息
function send(but) {//业务操作不变,省略代码//先加密let aesKey = aesUtil.genKey();let data = {data: aesUtil.encrypt(JSON.stringify({"type": "1","toUser": {"userId": toUserId},"fromUser": {"userId": fromUserId},"message": message,"date": nowTime}), aesKey),//AES加密后的数据aesKey: rsaUtil.encrypt(aesKey, sessionStorage.getItem('javaPublicKey')),//后端RSA公钥加密后的AES的keypublicKey: window.jsPublicKey//前端公钥
    };websocket.send(JSON.stringify(data));//业务操作不变,省略代码
}    

  后端收到后先解密

    /*** 服务器接收到客户端消息时调用的方法*/@OnMessagepublic void onMessage(String message, Session session) {try {//jacksonObjectMapper mapper = new ObjectMapper();//jackson 序列化和反序列化 date处理mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);//JSON字符串转 HashMapHashMap map = mapper.readValue(message, HashMap.class);//先解密String data = (String) map.get("data");String aesKey = (String) map.get("aesKey");//后端私钥解密的到AES的keybyte[] plaintext = RsaUtil.decryptByPrivateKey(Base64.decodeBase64(aesKey), RsaUtil.getPrivateKey());aesKey = new String(plaintext);//RSA解密出来字符串多一对双引号aesKey = aesKey.substring(1, aesKey.length() - 1);//AES解密得到明文data数据String decrypt = AesUtil.decrypt(data, aesKey);//JSON字符串转 HashMapHashMap hashMap = mapper.readValue(decrypt, HashMap.class);//得到hashMap,下面的业务操作跟前面的一样,这里就不贴出来了
} catch (Exception e) {e.printStackTrace();}}

  后端发送之前先加密,这里要用消息接收方的前端公钥进行加密

    /*** 封装一个send方法,发送消息到前端*/private void send(Session session, String message) {try {//发送前加密//每次响应之前随机获取AES的key,加密data数据String key = AesUtil.getKey();String data = AesUtil.encrypt(message, key);//用前端的公钥来解密AES的key,并转成Base64,注意:这里需要用接收方的前端公钥进行加密,从loginPublicKeyList集合获取String aesKey = Base64.encodeBase64String(RsaUtil.encryptByPublicKey(key.getBytes(), loginPublicKeyList.get(session)));//发送过去的是AES加密后的data,跟RSA加密后的aesKeysession.getBasicRemote().sendText("{\"data\":\"" + data + "\",\"aesKey\":\"" + aesKey + "\"}");} catch (Exception e) {e.printStackTrace();}}

  前端收到消息后先解密

//接收到消息的回调方法
websocket.onmessage = function (event) {let data = eval("(" + event.data + ")");//先解密let msgObj = aesUtil.decrypt(data.data, rsaUtil.decrypt(data.aesKey, window.jsPrivateKey));//业务操作不变,省略代码

};

  上线在线系统通知没有问题

  聊天没有问题

  后记

  第三版先到这里,后面我在整理一下WebSocket的AES与RSA混合加密,单独写一篇博客

转载于:https://www.cnblogs.com/huanzi-qch/p/10895703.html

一套简单的web即时通讯——第三版相关推荐

  1. 【分享】一套非常简单的企业即时通讯

    一套非常简单的企业即时通讯 今天的你今天不舒服的企业即时通讯,你今天不舒服,停下来歇歇吧,来到公园对面的企业即时通讯自来水厂,面条又薄又宽,在上面来回移动,小纪突然把手一松,我说,着食时,我们就进去了 ...

  2. 【项目需求说明书文档模板】WEB即时通讯规格说明书

    说明书 WEB即时通讯规格说明书 说明+需求+规格 详细模板联系我邮箱:lcyangmi@163.com 保密声明 本方案的内容属于个人.公司(XXXX)的知识财产,属于机密文档,将被限制做进一步的传 ...

  3. 什么是一套完全私有的即时通讯系统

    目前有很多组织机构仍旧在局域网中办公,非常重视企业内部数据安全,不适用完全开放的办公模式.因为,一些特殊组织机构的日常办公,除了要存放大量行政,财务,人事,甚至是技术交流,文档信息.还要考虑在局域网中 ...

  4. 融云 web 即时通讯

    融云 web 即时通讯 ☺ 官网https://www.rongcloud.cn/?utm_source=baiduBrand&utm_term=rongyun 老版本但更为详细的开发文档ht ...

  5. LEMP构建高性能WEB服务器(第三版)

    LEMP 自动化编译脚本下载:http://docs.linuxtone.org/autoinstall/ (定期更新,欢迎多测试,找bug) 介绍参考:http://bbs.linuxtone.or ...

  6. 环信即时通讯云iOS版V2.0.9.1服务评测

    集成测试 评测环境 2G/3G/WiFi网络下: 测评环境 MAC OS(10.9.2)+ XCode(5.1) + iPhone 测试对象 环信即时通讯云 IOS SDK Version 2.0.9 ...

  7. 环信即使通讯 php git,iOS即时通讯(三)- 环信SDK的导入

    注册环信账号 打开环信官方网站地址,注册选择即时通讯云,然后注册个人客户. 注册个人客户.png 提交后,打开邮箱验证环信注册,验证成功后即注册成功. 注册成功.png 创建应用 注册成功,登录环信即 ...

  8. WEB即时通讯/消息推送

    写在前面 通常进行的Web开发都是由客户端主动发起的请求,然后服务器对请求做出响应并返回给客户端.但是在很多情况下,你也许会希望由服务器主动对客户端发送一些数据. 那么,该如何实现这个需求,或者说该如 ...

  9. [nginx] LEMP构建高性能WEB服务器(第三版)

    LEMP 自动化编译脚本下载:http://docs.linuxtone.org/autoinstall/ (定期更新,欢迎多测试,找bug) 介绍参考:http://bbs.linuxtone.or ...

最新文章

  1. 带您走进七周七语言的程序世界
  2. npm nodejs包管理工具 简介
  3. 【快乐水题】1816. 截断句子
  4. 建立ARM交叉编译环境 (arm-none-linux-gnueabi-gcc with EABI)
  5. python中怎样向字典中添加值_python的字典中,如何向指定路径添加值?
  6. #import和@class 的区别
  7. atitit.提取zip rar文件列表 java php c# 的原理与设计
  8. 请问投稿中要求上传的author_SCI投稿状态解析
  9. 算法题04:分治法:求第K小元素(线性时间选择算法)
  10. js获取多叉树的广度和深度
  11. php nts ts 版本区分
  12. 网络工程师/计算机网络知识如何入门,以及学习路线?
  13. 20170321多益在线笔试(二笔)
  14. 49 把字符串转换成整数
  15. 动态网站作业4-JSP中实现数据库的增删改查的操作
  16. Q/W防洪跳转页面/微信小程序跳转到未备案域名
  17. Android-Dialogs(一) AlterDialog基本使用
  18. 怀揣巨资等了一季 陈天桥距门户野心咫尺之遥
  19. 微信小程序获取unionID思路整理
  20. 震惊!小伙竟然用python找出了马大师视频中的名场面

热门文章

  1. 必备小工具百度翻译桌面版,瞬时翻译
  2. Python中的错误和异常
  3. 图像压缩编码基础——笔记整理
  4. centos7开启网卡命令_CentOS7 开启网卡,设置开机启用网卡
  5. python矩阵运算,转置,逆运算,共轭矩阵
  6. 深圳搬家为什么要那么多注意事项
  7. 计算机外观保养的建议,网际电脑如何建议客户您怎样保养电脑
  8. 智能手环数据研究2——数据准确性研究简易评估
  9. html5 拍照 苹果手机黑屏,苹果手机拍照黑屏怎么办?iphone拍照黑屏的解决办法...
  10. 关于使用深度学习进行三维点云几何压缩