我们公司是做即时通讯软件的,客户要求实现端到端加密,群聊和私聊,并且第三方无法解密.


群聊的逻辑:

假如有十个人用户,user1....user10,

用户的设备 非对称加密算法是RSA,本地生成自己独有的公钥,私钥;

然后把公钥存到redis或者数据库中,
私钥有点特殊,用 用户的明文密码(比如:123456)作为对称加密的key加密privateKey后再存到redis或者数据库中,
这样即使后台运维人员看到privateKey也是加密过的;

User1 在数据库中存了 userId,username,password,privateKey,publicKey

在另外一台设备登录,则要下载公钥私钥,然后用明文的密码(123456)解密 被对称加密了的私钥,得到真正的私钥;
其他用户以此类推

User1拉user2-user10进群,

建群的过程中,用random函数随机生成一个UUID(以下叫做,randomKey),比如:
7f194fe1ec2740a58548ddb4e7222386

然后 用这十个用户的公钥加密randomKey,再发送给用户的设备上,
user1-user10 用各自的私钥解密,得到真正的randomKey,保存到本地;

以后发送消息都用randomKey,作为对称加密的key,加密消息内容,解密也是;
注意:randomKey在数据库中是不保存的,为了防止后台人员搞事情

当然,如果 政府机构要求,消息内容进行审查,则需要保存randomKey;

拓展:
假如user9本地的randomKey丢失了,则user9需要生成新的公钥和私钥,然后再存到数据库中,并且发送他的公钥到群里,
只要其中的一位群友,下载他的公钥,用他的公钥加密randomKey后再发给user9,user9用他自己私钥解密,得到randomKey,就能解密群消息了;

如果群里有1000条消息,然后所有群成员都丢失了randomKey,则采用折中的方法:
生成新的randomKey,然后再走一遍上面的逻辑;

结果显而易见,那1000条消息是解密不了了,好在群还能保留着,不然这个群就废了;


单聊:
用到了DH加密算法

1) Alice和Bob各自创建符合DH协议的密钥对,假设Alice密钥对为(私钥A,公钥A),Bob密钥对为(私钥B,公钥B);
2) 双方发送自己的公钥给对方,即使有黑客监听,他只能得到公钥A,公钥B;
3) Alice用自己的私钥和Bob的公钥计算消息密钥为S,即DH(私钥A,公钥B)=密钥S;
4) Bob用自己的私钥和Alice的公钥计算消息密钥也为S;即DH(私钥B,公钥A)=密钥S;
5) 双方同时确定了协商密钥S,后续可以通过S衍生出消息密钥,进行加密通讯。
6) 黑客只知道公钥A和公钥B,因为不知道任意一方的私钥,所以无法计算出密钥S。
综上可知,2个密钥对可以安全地创建一个“协商密钥”。在加密通讯中使用DH协议创建密钥,是非常安全的方法。

用户A 用户B 用户C 
公钥 公钥 公钥 公钥
私钥 私钥 私钥 私钥

A和B,B和A通讯:
DH(私钥A,公钥B)=密钥XXXS;
DH(私钥B,公钥A)=密钥XXXS;

A和C,C和A通讯:
DH(私钥A,公钥C)=密钥XXXB;
DH(私钥C,公钥A)=密钥XXXB;

也就是说,单聊,每个用户都有一对公钥私钥,但是两两之间,公钥私钥结合,就会有不同的秘钥;

私钥有点特殊,用 用户的明文密码(比如:123456)作为对称加密的key加密privateKey后再存到redis或者数据库中,
在另外一台设备登录,则要下载公钥私钥,然后用明文的密码(123456)解密 被对称加密了的私钥,得到真正的私钥;