我想做一个测试应用程序,它使用client从客户端到服务器进行通信。
“鲍勃”和“爱丽丝”总是有一个例子。这很好,但是他们从来没有展示过如何以安全的方式通过网络交换公钥。
那么,建议如何将公钥交换为"alice/client“和"bob/server”。
他们总是使用同一个文件或同一台机器来生成密钥对。
下面是libsodium扩展的摘录:
$alice_kp = crypto_box_keypair();
$alice_secretkey = crypto_box_secretkey($alice_kp);
$alice_publickey = crypto_box_publickey($alice_kp);
$bob_kp = crypto_box_keypair();
$bob_secretkey = crypto_box_secretkey($bob_kp);
$bob_publickey = crypto_box_publickey($bob_kp);
$alice_to_bob_kp = crypto_box_keypair_from_secretkey_and_publickey
($alice_secretkey, $bob_publickey);
$bob_to_alice_kp = crypto_box_keypair_from_secretkey_and_publickey
($bob_secretkey, $alice_publickey);
$alice_to_bob_message_nonce = randombytes_buf(CRYPTO_BOX_NONCEBYTES);
$alice_to_bob_ciphertext = crypto_box('Hi, this is Alice',
$alice_to_bob_message_nonce,
$alice_to_bob_kp);
$alice_message_decrypted_by_bob = crypto_box_open($alice_to_bob_ciphertext,
$alice_to_bob_message_nonce,
$bob_to_alice_kp);
$bob_to_alice_message_nonce = randombytes_buf(CRYPTO_BOX_NONCEBYTES);
$bob_to_alice_ciphertext = crypto_box('Hi Alice! This is Bob',
$bob_to_alice_message_nonce,
$bob_to_alice_kp);
$bob_message_decrypted_by_alice = crypto_box_open($bob_to_alice_ciphertext,
$bob_to_alice_message_nonce,
$alice_to_bob_kp);发布于 2014-04-08 23:23:23
direct不提供任何直接的密钥交换方法。您可以通过几种不同的方式安全地进行密钥交换:
如果您控制了客户端
由于您可能不希望重新实现SSL/TLS,第一个或第三个选项可能是最好的。但是,在客户机/服务器格式中,第一种方式有点困难,因为PHP服务器可能只有互联网才能进行通信。
但是,如果控制客户端,则可以执行证书固定。也就是说,将Bob的公钥嵌入Alice的可执行文件中。然后,Alice只会用Bob的公钥加密消息。
例如,Alice使用Bob的公钥和自己的私钥对一些数据进行加密,并将其发送给Bob(连同惟一的nonce和Alice的公钥)。
Bob使用他收到的公钥和他自己的私钥来解密和验证加密的数据包。对于Bob来说,使用任何数据都是安全的,因为只有他和Alice才能解密。
中间的男人呢?
好吧,伊芙可以屏蔽爱丽丝的信息并发送伊芙的公钥,但她可能是瞎了,因为爱丽丝只会发送用爱丽丝的私钥和鲍勃的公钥加密的信息。
在鲍勃看来,她只是另一个客户。在爱丽丝的眼里,她会很沮丧,因为鲍勃似乎没有反应。
如果Eve发送Alice消息,它们总是被标记为无效,因为Alice使用Alice的私钥,Bob的公钥试图解密它们,这将失败,因为Eve没有Bob的私钥。
如果Alice没有经过验证的可执行文件,Eve可能会在下载时修改它(并插入Eve的公钥而不是Bob的公钥)。验证可以通过她的包管理器,应用商店(大多数使用一些用于代码签名& SSL/TLS下载)或签名的可执行文件/源tarball。
有关泄露私钥的说明见此答案的最后一节.
防篡改分布
在客户端的用户以某种方式(使用特定于用户的密码或将来使用SQRL)验证自己之后,您可以在HTTPS网站上提供QR代码。QR代码显示,客户端可以通过在OS中注册自己作为uri协议的处理程序来扫描或链接自定义协议。
上述QR代码/ uri方法的一个不那么复杂的替代方法是让用户复制粘贴上面提到的HTTPS站点的共享秘密,该秘密将用于使用钠的crypto_secretbox()方法进行初始公钥交换。
请注意,共享密钥/公钥可能应该是在传输期间编码的base64、base32或十六进制,因为密钥中的一些字节可能会被不同的字符编码破坏。
如果服务器的私钥被泄露了怎么办?
如果您希望在私钥泄漏时使用前向保密,那么初始的公钥/私钥对应该只用于交换从未保存到永久存储介质(本质上是没有磁盘或数据库)的第二轮公钥。因为您的情况只是一个测试应用程序,所以前向保密可能并不是很重要。
第二轮密钥每隔一段时间就会被丢弃(就像每24小时一样),减少过去的数据由于诸如OpenSSL的心脏出血之类的错误而变得脆弱的风险。
在传统的使用PHP的are服务器中,这可能很难做到,因为每个HTTP请求都会重置所有变量。适当配置的memcached实例可能是一个选项,但有泄漏临时私钥的风险。
https://stackoverflow.com/questions/22552341
复制相似问题