在两个客户端之间发送消息,如何验证发件人的身份?

时间:2010-11-03 12:24:36

标签: c# .net encryption rsa encryption-asymmetric

因此假设您有两个客户端,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 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

任何在客户端和服务器之间发送消息的人都可以伪造新消息,客户端GUID永远不会改变,也不会RSA-ENCRYPTED-GUID

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

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

但是,任何监视消息的人都可以重新发送以前发送的消息。

答案 3 :(得分:0)

公钥和私钥是可行的方法。我假设你不关心加密数据,但你确实关心数据是“授权的”。

假设你有3台电脑

器Comp1 COMP2 COMP3

让我们再说你希望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以用作查找以决定使用哪些公钥。

P.S。您将需要使用内置方法来签名消息。让框架执行散列/ etc