前言

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

  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混合加密完整实例
<https://www.cnblogs.com/huanzi-qch/p/10913636.html>



  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>(); /** * 连接建立成功调用的方法 */ @OnOpen
public 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的key publicKey:
window.jsPublicKey//前端公钥 }; websocket.send(JSON.stringify(data)); //业务操作不变,省略代码
}
 

  后端收到后先解密
/** * 服务器接收到客户端消息时调用的方法 */ @OnMessage public void onMessage(String message,
Session session) {try { //jackson ObjectMapper mapper = new ObjectMapper(); //
jackson 序列化和反序列化 date处理 mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd
HH:mm:ss")); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,
false); //JSON字符串转 HashMap HashMap map = mapper.readValue(message, HashMap.class
);//先解密 String data = (String) map.get("data"); String aesKey = (String)
map.get("aesKey"); //后端私钥解密的到AES的key byte[] 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字符串转 HashMap HashMap 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加密后的aesKey
session.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混合加密,单独写一篇博客

友情链接
ioDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:637538335
关注微信