1

因此,假设您有两个客户端,C1 和 C2,每个客户端都有一个与之关联的 GUID。

当您在 C2 上收到据称来自 C1 的消息时(通过检查 GUID 并查看它是否与 C1 的 GUID 匹配),但由于不能保证消息来自 C1(C3 可能刚刚发送消息,在消息头中发送 C1 的 GUID)必须验证消息实际上来自 C1。

我一直在研究使用非对称加密 (RSA) 让 C1 发送由 组成的消息,[C1.GUID; RSAEncrypt(C2.PUBLIC_KEY, C1.GUID); MESSAGE]然后让 C2 基本上进行这样的检查(python 伪代码):

message.GUID == RSADecrypt(C2.PRIVATE_KEY, message.ENCRYPTED_GUID)

这是一种可行的方法吗?还是有其他一些更聪明/更明显的方法来验证消息的发件人?

4

4 回答 4

2

非对称算法就是为此目的而发明的,这就是数字签名的工作方式。

但是,您的方法存在一些问题。任何拥有收件人公钥的人都可以伪造签名。此外,签名根本没有改变!任何拦截消息的人都可以伪装成有效的发件人。非对称加密的目的是通过密钥交换来解决这些问题,这是数字签名的概念,它基本上是您正在折腾的消息的非对称加密哈希。

对于 RSA,您需要做更多工作才能从基本算法创建数字签名,请参阅维基百科了解更多详细信息:http ://en.wikipedia.org/wiki/RSA#Signing_messages

我只是使用图书馆中的数字签名算法。对于 Python,第一个谷歌搜索出现了这个:

http://www.example-code.com/python/pythonrsa.asp

http://www.chilkatsoft.com/dsa-python.asp

于 2010-11-03T12:38:58.437 回答
0

这种方法的问题是任何机器都可以捕获 guid 和 rsa-encrypted-guid 并以相同的方式传递它们。您还没有真正创建任何只能由接收客户端预测的独特挑战/响应标准。您需要的是完全独特的东西,不能仅仅通过查看传递的参数来获得。也许是这样的:

[ClientName; RSA-ENCRYPTED(GUID+Timestamp); MESSAGE]

在这种方法中,RSA 加密将使用 Client2 的公钥完成,因此只有 Client2 的私钥才能解锁它。使用 ClientName,Client2 可以从数据源检索预期的 GUID,然后将返回的 GUID 与加密中的 GUID 匹配。我将时间戳的使用结合为盐,以便加密的字符串每次都以不同的方式出现。使用时间戳作为盐的随机化被认为是非常弱的,但它明白了这一点。可以实现其他更安全/随机的算法。

于 2010-11-03T12:37:31.707 回答
0

任何在客户端和服务器之间监视消息的人都将能够伪造新消息,客户端GUID永远不会改变,也不会RSA-ENCRYPTED-GUID.

考虑切换到此消息模型:[GUID; ENCRYPTED_CONTENT_CHECKSUM; CONTENT]

Checksum(message.CONTENT) == 
    RSADescrypt(C1.PUBLIC_KEY, message.ENCRYPTED_CONTENT_CHECKSUM)

尽管如此,任何监视消息的人都可以重新发送以前发送的消息。

于 2010-11-03T12:42:19.160 回答
0

公钥和私钥是要走的路。我假设您不关心加密数据,但您确实关心数据是“授权的”。

假设你有 3 台电脑

比较 1 比较 2 比较 3

假设您希望 Comp1 向 Comp3 发送消息。您不在乎消息是否被截获,但您确实在乎它不是伪造的。

Comp1 将使用其私钥对消息进行数字签名

Comp2 会拦截 Comp1 到 Comp3 的消息,但不能在不使签名失效的情况下更改消息

Comp2 将消息转发到 Comp3

Comp3 将使用 Comp1 的公钥解密签名并使用签名中的散列来验证内容。

现在如果你想加密数据,你需要添加一个额外的步骤

Comp1 将使用其私钥对消息进行数字签名

Comp1 将生成一个随机加密密钥(通常为 AES)并对消息进行加密。

Comp1 将获取该加密密钥并使用 Comp3 的公钥对其进行加密

Comp2 会拦截消息,但没有 Comp3 的私钥就无法读取消息

Comp2 将消息转发到 Comp3

Comp3 将使用它的私钥来解密 AES 密钥

Comp3 将使用 AES 密钥解密整个消息

Comp3 将通过使用 Comp1 的公钥解密签名来验证消息。

签名包含消息的散列,如果散列和消息的散列匹配,则数据是完整的。

您可以在有效负载中包含 GUID,以用作查找来决定使用哪些公钥。

PS您将需要使用内置方法来签署消息。让框架做散列/等

于 2010-11-03T17:19:29.590 回答