因此,假设您有两个客户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)

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

有帮助吗?

解决方案

出于此类目的,已经发明了分类算法,这就是数字签名的工作方式。

但是,您的方法有一些问题。拥有接收者公共钥匙的任何人都可以伪造签名。另外,签名根本不会改变!任何拦截消息的人都可以伪造成为有效的发件人。评估加密的目的是通过关键交换来打败这些问题,存在数字签名的概念,这基本上是您所丢弃的信息的合理加密的哈希。

对于RSA,您需要做更多的事情才能从基本算法中创建数字签名,请参见Wikipedia,有关更多详细信息: http://en.wikipedia.org/wiki/rsa#signing_messages

我只使用库中的数字签名算法。首先,Google搜索对Python的出现:

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

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

其他提示

这种方法的问题在于,任何机器都可以捕获GUID和RSA加密指示,并将其传递给它们。您并没有真正创建任何只能由接收客户端来嘲笑的唯一挑战/响应标准。您将需要的是完全独特的东西,并且不能简单地查看经过的参数就能获得。也许类似:

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

在此方法中,RSA加密将使用Client2的公共密钥完成,以便只有Client2的私钥才能解锁。使用客户名称,客户端2可以从数据源检索预期的GUID,然后将返回的GUID与加密中的GUID匹配。我将时间戳的用法纳入了盐,因此每次加密的字符串都会出现不同。使用时间戳作为盐的随机化被认为是非常弱的,但是它的意思是。可以实现其他更安全/随机的算法。

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

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

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

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

公共和私钥是必经之路。我会假设您不在乎加密数据,但是您确实在乎数据已授权。

假设您有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的公钥解密签名来验证消息。

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

您可以在有效载荷中包含GUIDS,以确定要使用哪种公共密钥。

PS您将需要使用内置方法签署消息。让框架进行哈希/等

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top