Giter Site home page Giter Site logo

Signal协议 js使用 about blog HOT 20 OPEN

z-950 avatar z-950 commented on June 13, 2024
Signal协议 js使用

from blog.

Comments (20)

dzcpy avatar dzcpy commented on June 13, 2024

非常不错的文章!想请教下群聊如何做 e2e 加密呢?

from blog.

1111mp avatar 1111mp commented on June 13, 2024

请问有完整的使用demo吗 我搞了很久 一点头绪都没有 直接把这些代码拷过来执行 很多报错 比如

KeyHelper.generatePreKey(keyId).then(function (preKey) {
		store.storePreKey(preKey.keyId, preKey.keyPair);
	});

这里的keyId是从哪里来的 是需要自己提供 还是怎么样

from blog.

z-950 avatar z-950 commented on June 13, 2024

@dzcpy
没有做过群聊加密。js的实现库内缺少群聊加密的方法。但其java版本有,可以参考然后自行实现。

from blog.

z-950 avatar z-950 commented on June 13, 2024

@1111mp
没有demo。此文写于一年前。按照我的记忆和查看依赖库的部分代码,keyId是自行生成的,不同用户的keyId可以重复,keyId主要用于存取key。

from blog.

1111mp avatar 1111mp commented on June 13, 2024

@z-950 谢谢回复。刚入手,用都不会用。。。不过在社区找到了一个大佬的帖子,应该有帮助。
@dzcpy https://community.signalusers.org/t/an-unofficial-signal-chatbot-and-javascript-library/4767 群聊的也实现了
目前我还是没有入门成功 唉 但是他是封装好的 用的signal的服务 还是得自己实现

from blog.

z-950 avatar z-950 commented on June 13, 2024

@1111mp 运行例子确实难找。实际上难点还有后端部署和网络交互接口。客户端方面也许还可以参考测试代码。

from blog.

1111mp avatar 1111mp commented on June 13, 2024

@z-950 这个不能单纯的用来做消息的加密和解密吗?比如我有自己的IM服务 现在只差一个端到端加密 我就想用这个加密一下 发送的消息的字符串。这样可行吗?

from blog.

z-950 avatar z-950 commented on June 13, 2024

@1111mp 因为我没有完整实现过,所以不能肯定的告诉你是否可以。但是理论上,后端也需要相关的功能。端到端加密为了安全性,设计了特定的密/公钥交换规则,后端一定需要实现这部分内容,这要求你对这些规则有所了解。自然,我不太清楚全部的流程。Signal有文档,你可以结合着它后端的例子看。
如果你不需要如此高的安全性,你大可以自行实现一种协议。

from blog.

1111mp avatar 1111mp commented on June 13, 2024

@z-950 官方的文档就是看不懂啊 写的都一笔带过 然后自己就在摸索 根据这个人的用法 issues32 目前大概知道怎么去使用了 服务器需要保存一些pubKey 然后客户端根据这个pubKey和自己的priKey 建立回话 然后加密解密可以做到 但是官方文档说 ‘客户端会生成单个已签名的PreKey以及大量未签名的PreKey,并将它们全部传输到服务器。’这个不是很懂

const preKey = await KeyHelper.generatePreKey(keyId);

这个生成的preKey 本身就已经做到了吗 还是说需要执行大量的这个方法去存到服务器
然后目前只简单了解到这里了 群聊的 想都不敢想

from blog.

z-950 avatar z-950 commented on June 13, 2024

这个生成的preKey 本身就已经做到了吗 还是说需要执行大量的这个方法去存到服务器

@1111mp
每次只生成一个preKey。自己按需生成。

from blog.

1111mp avatar 1111mp commented on June 13, 2024

每次只生成一个preKey。自己按需生成。
@z-950 可以这样理解吗

const promise = sessionBuilder.processPreKey({
				registrationId,
				identityKey: identityKeyPair.pubKey,
				signedPreKey: {
					...signedPreKey,
					publicKey: signedPreKey.keyPair.pubKey
				},
				preKey: {
					...preKey,
					publicKey: preKey.keyPair.pubKey
				}
			});

验证的时候需要的这些参数 都是在跟客户端对应的 安装客户端的时候生成一次就行?

from blog.

1111mp avatar 1111mp commented on June 13, 2024

@z-950

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Bob</title>
	<script type="text/javascript" src="./libsignal-protocol.js"></script>
	<script type="text/javascript" src="./store.js"></script>
</head>

<body>
	<script>
		var KeyHelper = libsignal.KeyHelper;
		var store = new SignalProtocolStore();

		generateKeys(123, function (aliceKeys) {
			store.put('identityKey', aliceKeys.identityKeyPair);
			store.put('registrationId', aliceKeys.registrationId);
			console.log('aliceKeys.registrationId', aliceKeys.registrationId)

			generateKeys(456, function (bobKeys) {

				console.log('bobKeys.registrationId', bobKeys.registrationId)

				var recipientId = "daniel123";
				var deviceId = 0;
				var address = new libsignal.SignalProtocolAddress(recipientId, deviceId);

				// Instantiate a SessionBuilder for a remote recipientId + deviceId tuple.
				var sessionBuilder = new libsignal.SessionBuilder(store, address);

				// Process a prekey fetched from the server. Returns a promise that resolves
				// once a session is created and saved in the store, or rejects if the
				// identityKey differs from a previously seen identity for this address.
				var promise = sessionBuilder.processPreKey({
					registrationId: bobKeys.registrationId,
					identityKey: bobKeys.identityKeyPair.pubKey,
					signedPreKey: {
						keyId: bobKeys.signedPreKey.keyId,
						publicKey: bobKeys.signedPreKey.keyPair.pubKey,
						signature: bobKeys.signedPreKey.signature
					},
					preKey: {
						keyId: bobKeys.preKey.keyId,
						publicKey: bobKeys.preKey.keyPair.pubKey
					}
				});

				promise.then(function onsuccess() {
					// encrypt messages
					console.log("Vamo a encriptar");
				});

				promise.catch(function onerror(error) {
					// handle identity key conflict
					console.log(error);
				});

				const plaintext = "Hello world";
				// let ciphertext;
				const sessionCipher = new libsignal.SessionCipher(store, address);
				console.log(sessionCipher)
				sessionCipher.encrypt(plaintext).then(function (ciphertext) {
					// ciphertext -> { type: <Number>, body: <string> }
					console.log('ciphertext:', ciphertext)
					// ciphertext = ciphertext;
					// handle(ciphertext.type, ciphertext.body);

					// var sessionCipher = new libsignal.SessionCipher(store, address);
					// sessionCipher.decryptWhisperMessage(ciphertext.body).then(function (plaintext) {
					// 	// handle plaintext ArrayBuffer
					// 	console.log(plaintext)
					// });

					var addressCopy = new libsignal.SignalProtocolAddress(recipientId, deviceId);
					var sessionCipherCopy = new libsignal.SessionCipher(store, addressCopy);

					// 首先建立一个新的会话来解密PreKeyWhisperMessage。
					// 返回一个承诺,该承诺将在消息解密时解析,或者如果identityKey与该地址先前看到的身份不同,则拒绝。
					sessionCipherCopy.decryptPreKeyWhisperMessage(ciphertext.body).then(function (plaintext) {
						// handle plaintext ArrayBuffer
						// 处理纯文本ArrayBuffer
						console.log(plaintext)
					}).catch(function (error) {
						// handle identity key conflict
						// 处理身份密钥冲突
						console.log(error)
					});

				});
			});

		});


		function generateKeys(keyId, callback) {

			var keys = {};
			keys.registrationId = KeyHelper.generateRegistrationId();
			// Store registrationId somewhere durable and safe.
			KeyHelper.generateIdentityKeyPair().then(function (identityKeyPair) {
				// keyPair -> { pubKey: ArrayBuffer, privKey: ArrayBuffer }
				// Store identityKeyPair somewhere durable and safe.
				keys.identityKeyPair = identityKeyPair;

				KeyHelper.generatePreKey(keyId).then(function (preKey) {
					store.storePreKey(preKey.keyId, preKey.keyPair);
					keys.preKey = preKey;

					KeyHelper.generateSignedPreKey(identityKeyPair, keyId).then(function (signedPreKey) {
						store.storeSignedPreKey(signedPreKey.keyId, signedPreKey.keyPair);
						keys.signedPreKey = signedPreKey;
						callback(keys);
					});
				});
			});

		}
	</script>
</body>

</html>

我这么使用的时候 加密成功了 解密一直失败 解密的时候

var addressCopy = new libsignal.SignalProtocolAddress(recipientId, deviceId);
					var sessionCipherCopy = new libsignal.SessionCipher(store, addressCopy);

					// 首先建立一个新的会话来解密PreKeyWhisperMessage。
					// 返回一个承诺,该承诺将在消息解密时解析,或者如果identityKey与该地址先前看到的身份不同,则拒绝。
					sessionCipherCopy.decryptPreKeyWhisperMessage(ciphertext.body).then(function (plaintext) {
						// handle plaintext ArrayBuffer
						// 处理纯文本ArrayBuffer
						console.log(plaintext)
					}).catch(function (error) {
						// handle identity key conflict
						// 处理身份密钥冲突
						console.log(error)
					});

addressCopy的recipientId和deviceId不是用的同一个吗
能指教一下吗

from blog.

z-950 avatar z-950 commented on June 13, 2024

验证的时候需要的这些参数 都是在跟客户端对应的 安装客户端的时候生成一次就行?

@1111mp 按照介绍,安装时都需要生成,并且持久化储存。后续聊天需要使用新生成的preKey。

from blog.

1111mp avatar 1111mp commented on June 13, 2024

@z-950 好的 谢谢 解密刚刚已经成功了 signalapp/libsignal-protocol-javascript#41 非常感谢

from blog.

1111mp avatar 1111mp commented on June 13, 2024

@z-950 就是 每发一条消息 都需要生成 一个preKey 每个消息的preKey都不一样 这样吗

from blog.

dzcpy avatar dzcpy commented on June 13, 2024

各位如果感兴趣的话,不如拉个群一起研究?这块我肯定是要实现一套方案出来的。这样多个人还能多点思路,简化开发

from blog.

1111mp avatar 1111mp commented on June 13, 2024

@dzcpy 我自己刚建了一个qq群,691383606 有时间一起沟通下

from blog.

1111mp avatar 1111mp commented on June 13, 2024

@dzcpy 看你也没有回复,我在这里分享一下,我自己理解的一种端到端加密的方案:
simple_signal
跟signal protocal的安全性肯定没法比,但是它实在太难了,而且几乎没有相关的基础的文档,太费劲了。有点力不从心。
不过在整理这个的时候,我好想对signal protocol有了更深的理解,后续我看能不能整理出一个完整的简单的从0到1的例子出来。祝我这段时间少掉点头发吧。唉。

from blog.

GavinZJM avatar GavinZJM commented on June 13, 2024

想问下 加密解密都通了 但是这里app说 要本地存储session 用来存储棘轮的状态 方便未读消息解密 那这里拿到session 要怎么把他嵌入 原生代码 逻辑里 能否提供下

from blog.

xie392 avatar xie392 commented on June 13, 2024

想问下 加密解密都通了 但是这里app说 要本地存储session 用来存储棘轮的状态 方便未读消息解密 那这里拿到session 要怎么把他嵌入 原生代码 逻辑里 能否提供下
你解决了吗,我加密解密都行,但是不知道怎么存session,现在每次进去都会重新建立一个会话,导致之前的消息无法解密出来,只能解密当前会话的消息,这个会话如何存储?又怎么恢复?这是我的一个简单demo

from blog.

Related Issues (7)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.