有没有什么加密算法是一对多的?

2020-08-07 06:58:59 +08:00
 lihongming

有个项目可能需要用到一对多的加密传输,但我对加密没研究,求大佬们帮忙推荐个加密算法。

需求如下:

客户端: 每个客户端有自己的 key,发往服务端的信息都要用 key 加密后传输

服务端: 接收客户端发过来的加密信息,然后用自己的 key 解密,并且能验证客户端身份(比如客户端编号是 123,则其必须用 123 的 key,或者 key 本身带编号也可)

管理端: 可以根据服务端的 key 和客户端的编号生成无数多个客户端的 key

服务端、客户端、管理端都是脱机运行的,不联网。所以更新服务端名单的方法不能用,只能依靠加密算法。

4189 次点击
所在节点    程序员
24 条回复
singerll
2020-08-07 07:16:16 +08:00
非对称加密。。。
RecursiveG
2020-08-07 07:19:42 +08:00
标准证书系统。

你在管理端生成一对 CA 密钥对,把公钥丢到服务端去。然后给每个客户端生成私钥证书对,用 CA 私钥给证书签名。客户端用自己的私钥给数据签名并连着有 CA 签名的证书一起发给服务端。最后服务端用 CA 公钥检查客户端传过来的证书的签名。

至于数据加密具体怎么做看你需求。
steven_yue
2020-08-07 07:33:51 +08:00
kerberos
nvkou
2020-08-07 07:41:37 +08:00
这不就是证书链吗。服务器做个 CA,然后给各个客户端签发证书就是
xyjincan
2020-08-07 09:11:25 +08:00
GPG keys 你弄一个,所有客户端都能给你发数据啦,只保存一个就行,客户端自己带个编号,检查一下就行
phpfpm
2020-08-07 09:23:54 +08:00
u1s1 服务端客户端管理端都不联网那么之间是怎么沟通的。。。。
zealic
2020-08-07 09:34:36 +08:00
可以看看 Bitcoin 的 HD 钱包是怎么设计的。
最终的结果就是一个根密钥,对应到几乎无限的公钥。
根密钥所有者可以推导处所有私钥,派生父公钥持有者只能推导自己的下级公钥。

https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
geelaw
2020-08-07 10:20:53 +08:00
你需要的是一种高级签名算法和一种普通加密算法,因为你的要求是“验证客户端身份”,发送者有无数个,但接收者只是服务器一个。搜索 identity-based signature 有惊喜。
Vegetable
2020-08-07 10:25:23 +08:00
这个没什么特别的,比如 jwt 的 token,每次登录返回的都可以不一样。你只要在生成的时候填入不重复的填充信息就好了。
常见的非对称加密比如 RSA 加密,也是有加盐过程的,每次加密的结果也不一样。其实都是一回事儿,加入点会变的垃圾就完了。
jimmyismagic
2020-08-07 10:26:26 +08:00
反正我知道 HD 钱包可以,ECC 本身既可以用于签名也可以用来加解密
diaryevil
2020-08-07 10:32:12 +08:00
基于对称加密和非对称加密的证书+SSL 方式
qwerthhusn
2020-08-07 10:34:28 +08:00
这种场景挺适合用 CA 签发证书的,如果是在线的话,直接 TLS 客户端认证即可。如果是离线的话,实现类似的功能比较麻烦了。。

其实可以用一个非常简单的方案。。全程都用 AES (不用什么非对称加密或者数字签名)
因为非对称加密只能加密一些比较小的数据,比较大的数据加密非常慢(一般都是先生成个临时的对称加密的 key,然后数据用这个 key 加密,最后再把 key 用非对称的加密一下)

如下:::
服务器存一个 key 叫 sk

新增客户端:生成一个 key 叫 ck
然后将客户端标志和 ck 加密一下得到 cke (还可以附带一些其他信息,比如 失效时间等)
将 ck 和 cke 发给客户端(假设发送数据的链路是安全的,就是不会被截获,不安全的话就可能要用 DH 这类算法了)

客户端每次请求的时候,用 ck 把数据加密
然后发送给服务器加密的数据和这个 cke ( ck 不能发)

这时服务端拿着 cke 用 sk 解密获得 ck 和用户信息
然后用获得的 ck 去解密数据
这两步只要有一步解密失败说明数据不合法

这个够简单吧。
xiangyuecn
2020-08-07 10:50:06 +08:00
哪有怎么复杂,还要上 CA 体系?

看需求,生成一对 RSA 密钥就完全够了,服务端持有 RSA 私钥,客户端持有 RSA 公钥。

客户端传输时( U 盘?),随机生成一个 key (或者固定的机器码),用 RSA 公钥加密这个 key 生成密文 A,用 key 加密实际的数据生成密文 B,把 A 、B 组合到一起(生成一个文件放到 U 盘)传输。

服务端收到数据后,拆分出 A 、B 密文,用私钥解密得到客户端随机 key,用 key 解密数据 B,得到实际数据。

全程脱机运行,只要 RSA 私钥不泄露,炒鸡安全。

----
不需要:“管理端: 可以根据服务端的 key 和客户端的编号生成无数多个客户端的 key” ,这个需求在这个体系下几乎没有意义。
shawndev
2020-08-07 10:52:59 +08:00
两种方式:
shawndev
2020-08-07 10:53:52 +08:00
1. 非对称加密数字信封:缺点是每新增一个接收方都要更新密钥部分
2. 代理重加密
lihongming
2020-08-07 10:56:41 +08:00
@phpfpm 通过 NFC 通讯的
no1xsyzy
2020-08-07 10:59:31 +08:00
这不是多对一吗?
littlewing
2020-08-07 11:08:25 +08:00
这不就是 ca 吗
lihongming
2020-08-07 11:11:53 +08:00
@xiangyuecn 谢谢,但这个设计的问题是无法授权客户端,因为公钥是公开的,任何人都可以拿着公钥说自己是合法的客户端。

但你的思路我懂了,只要改一下,让管理端来生成客户端的 key,再发给客户端,就可以实现授权了。但这样管理端用的 key 也不能公开了,也就不需要非对称算法了
keepeye
2020-08-07 11:15:43 +08:00
每个用户生成一对密钥,服务端保存私钥即可

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/696319

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX