【IM系列】IM如何实现端到端加密对话

前言

每次我们使用微信,有时候会想自己发的消息会不会被其他人监听到。特别是给自己的女朋友,发私密消息。还有就是微信管理员,会不会看你的私密消息。如果管理员想看你的,那么你也没办法。那有没一种方法,就是微信管理员也看不到你的私密消息内容。

上面说的管理员,实际就是服务端。而我们使用IM的人就是客户端,也就是要实现一个只有两个客户端能看到消息内容,即使是服务端也看不到。那么就更能保证用户的消息的隐私和信息安全。

上面说的要实现这个功能就是端到端加密,我们一起看看IM如何实现端到端加密。

端到端加密(End-to-End Encryption, E2EE)是一种安全通信的方式,其中只有通信的两个端点(通常是两个终端设备,例如用户的手机或计算机)能够理解或解密消息,而在通信路径的中间节点,包括服务提供者,都无法直接访问或理解消息内容。(Whatsapp支持)

实现思路

我们知道将消息加密,那么客户端A发送到服务端,服务端再转发到客户端B链路都是加密发送。那么不就是都是加密传输了,如果服务端也不知道密钥。那么服务端也就是看不到消息,解密后内容了。消息内容用对称加密AES,进行加解密。

这个前提,一个方案那么密钥发送线下传递。比如小明和小红,线下面对面。大家一起协商下密钥多少。大家都用这个密钥加解密,那么就可以愉快的进行私密聊天。

那万一,小明和小红是网友呢。也就是说彼此不能见面,那么怎么传递密钥。

上面的AES加密过程是需要将密钥加密后发送给对方,也就是一方需要加密,而另一方只需要解密。发明一种密码加密用加密密钥,解密用解密密钥。发送者只需要加密密钥(公钥),解密者只需要解密密钥(私钥)。那么我将公钥发给对方,让他用AES密钥用公钥密码的公钥加密后发给我,而我再用私钥解密。
我们这边需要使用到是非对称加密。

非对称加密解决密钥配送问题(key distribution problem,密钥分发问题)。

这边涉及到两个密码学知识对称密码AES和非对称加密RSA,如果大家对这两个密码不是很熟悉。可以参考下笔者密码学总结,实现开放接口验签和加密这篇文章。

整体思路,就是客户端A生成RSA公私钥,客户端A将公钥发给客户端B。客户端B收到公钥,生成AES密钥,同时将AES密钥用收到的公钥进行加密。客户端B将加密后的AES密钥发给客户端A .客户端A收到RSA加密后的密钥。客户端A,用私钥解密,获得了AES密钥对。

在AES密钥传输过程中,因为除了客户端A其他人都不知道RSA私钥。也就无法知道AES密钥了。

代码实现

1.客户端A生成RSA公私钥,将公钥发给客户端B

    public void openE2EE(long userId) {
   
        final ChatChannelDTO chatChannelDTO = CHAT_CHANNEL_MAP.get(userId);
        final String[] keyPair = JiDigitUtil.genKeyPair(JiDigitUtil.RSA_ALGORITHM);
        String publicKeyBase64 = keyPair[0];
        String privateKeyBase64 = keyPair[1];
        chatChannelDTO.setPublicKey(publicKeyBase64);
        chatChannelDTO.setPrivateKey(privateKeyBase64);
        chatChannelDTO.setEncryptType(CommonStatusEnum.DISABLE.getStatus());
        privateMessage(publicKeyBase64, ChatMessageTypeEnum.RSA_PUBLIC_KEY.getCode(), userId);
    }

2.客户端B收到公钥,生成AES密钥,同时将AES密钥用收到的公钥进行加密

                case RSA_PUBLIC_KEY:
                    if (Objects.equals(clientInfo.getDeviceType(), DeviceTypeEnum.MOBILE.getCode())) {
   
                        //                    收到RSA公钥,那么生成E2EE 密钥发给对方。作为通信密钥
                        final String publicKey = chatSendMessage.getMessageContent();
                        final String secretKey = JiDigitUtil.genSecretKey(JiDigitUtil
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值