Zend_Crypt_DiffieHellman - 使用示例

发布于 2025-01-03 15:11:34 字数 198 浏览 1 评论 0原文

有使用 Zend_Crypt_DiffieHellman 类的示例吗?我正在尝试编写一个桌面应用程序,它将以安全的方式与 Zend Framework 上的 PHP 服务器进行通信。我一直无法理解如何在两方之间建立共享密钥。我需要获得一组我自己的素数吗?

任何有关如何使用它来获取共享密钥的示例将不胜感激!

我认为我真正的问题是如何获得素数和生成器!

Is there an example of usage Zend_Crypt_DiffieHellman class? I'm trying to write a desktop application which will comunicate with PHP server on Zend Framework in a secure manner. I'm stuck with understading how I can establish a shared key between two parties. Do I need to obtain a set of my own prime numbers?

Any example of how to use this to obtain shared key would be greatly appreciated!

I think my real question is how to get a prime number and a generator for it!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

清醇 2025-01-10 15:11:34

如何得到一个群(由素数和生成器组成)

我绝不是密码学专家,但我认为你应该使用 RFC 2412 - OAKLEY 密钥确定协议(附录 E.1)RFC 3526 中的组。在将十六进制数与 Zend_Crypt_DiffieHellman 一起使用之前,您可能必须先将它们转换为十进制数。

您应该使用哪个组?

越大越好——不,只是开玩笑。

取决于您计划如何实施密钥交换。如果您必须对每个 HTTP 请求执行 DH 交换,则更大的组将杀死您的服务器,因为这将花费更多时间来计算(但另一方面更难破解)。在我的示例中,我使用了 768 位的“Well Known Group 1”,它相当慢(好吧,我的开发机器不是最快的)。

您还可以添加服务器和客户端在第一步中就使用哪个预定义组达成一致的选项。例如:您随应用程序提供众所周知的组 1、2 和 5。在实际 DH 密钥交换之前,双方同意使用组 1 进行实际 DH 密钥交换。这样,当硬件赶上时,您可以切换到更大的组。当然,这个团体协议为您的密钥交换过程增加了另一个步骤。

Zend_Crypt_DiffieHellman 示例

这是一个简单的示例,没有实际将公共数据传输到另一个进程。

// why disable the use of openssl?
// apparently "computeSecretKey" uses the php function 
// openssl_dh_compute_key which expects an openssl "pkey" resource but
// the Zend Framework (1.11.4) supplies a string
Zend_Crypt_DiffieHellman::$useOpenssl = false;

// here I define the Well Known Group 1 (which consists of the prime and
// the generator) with a 768 bit prime. 
// These can be either hard coded ore your parties agree on which group to
// use in a separate step of the key-exchange process.
$public_prime =
    "155251809230070893513091813125848175563133404943451431320235" .
    "119490296623994910210725866945387659164244291000768028886422" .
    "915080371891804634263272761303128298374438082089019628850917" .
    "0691316593175367469551763119843371637221007210577919";
$public_generator = 2;

// if you want it to go fast use smaller values (these are from the
// Diffie Hellman entry on Wikipedia).
//$public_generator = 5;
//$public_prime = 23;

$bob = new Zend_Crypt_DiffieHellman($public_prime, $public_generator);
$alice = new Zend_Crypt_DiffieHellman($public_prime, $public_generator);

// first generate the private key and the public data on both sides
$bob->generateKeys();
$alice->generateKeys();

// you can access the public data using the "getPublicKey" method.
// You can transmit those values over the wire to the other party. 
echo "bob=", $bob->getPublicKey(), PHP_EOL;
echo "alice=", $alice->getPublicKey(), PHP_EOL;

// After both parties have received the public data from the other party
// they can calculate the shared secret:    
echo "shared(alice)=", $alice->computeSecretKey($bob->getPublicKey()), PHP_EOL;
echo "shared(bob  )=", $bob->computeSecretKey($alice->getPublicKey()), PHP_EOL;
// the values should be equal.

唯一真正通过线路传递的是 Zend_Crypt_DiffieHellman::getPublicKey 的返回值。公共数据可以编码为文本 (Zend_Crypt_DiffieHellman::NUMBER) 或二进制数据 (Zend_Crypt_DiffieHellman::BINARY)。

还有另一种:Zend_Crypt_DiffieHellman::BTWOC,它与二进制相同,但具有前导零字节,因此该整数不会被视为“有符号”整数 - 如果您的客户端应用程序使用 Java JCE 或.NET Crypto API,这可能是二进制传输的最佳选择。

主动提供的建议

如果您想让自己的生活更轻松,不要重新发明 SSL - 只需通过 HTTPS 使用现有的 SSL 实现即可。

大多数 SSL 库允许您检查服务器证书,因此请检查客户端上服务器证书的有效性(至少检查指纹)。

如果您需要或想要,您可以检查服务器上的客户端证书(请参阅使用 SSL使用 PHP 的客户端证书)。

How to get a group (consisting of a prime and a generator)

I am by no means a cryptography-expert but I think you should use the "Well-Known Groups" defined in RFC 2412 - The OAKLEY Key Determination Protocol (appendix E.1) or the groups from RFC 3526. You probably have to convert the hexadecimal numbers to decimal first before you use them with Zend_Crypt_DiffieHellman.

Which group should you use?

The bigger, the better - no, just joking.

Depends on how you plan to implement the key-exchange. If you have to execute the DH-exchange on each HTTP request, a bigger group will kill your server, because it'll take more time to compute (but are on the other hand harder to crack). In my example I've used the "Well Known Group 1" with 768 bits and it was fairly slow (okay my dev machine is not the fastest).

You can also add the option that the server and the client agree in a first step on which predefined group to use. For example: You deliver the well known groups 1, 2 and 5 with your application. And before the actual DH-key exchange your parties agree on using group 1 for the actual DH-key exchange. That way you can switch to the bigger groups as the hardware catches up. Of course this group-agreement adds another step to your key-exchange process.

Zend_Crypt_DiffieHellman example

This is a simple example without actually transmitting the public data to another process.

// why disable the use of openssl?
// apparently "computeSecretKey" uses the php function 
// openssl_dh_compute_key which expects an openssl "pkey" resource but
// the Zend Framework (1.11.4) supplies a string
Zend_Crypt_DiffieHellman::$useOpenssl = false;

// here I define the Well Known Group 1 (which consists of the prime and
// the generator) with a 768 bit prime. 
// These can be either hard coded ore your parties agree on which group to
// use in a separate step of the key-exchange process.
$public_prime =
    "155251809230070893513091813125848175563133404943451431320235" .
    "119490296623994910210725866945387659164244291000768028886422" .
    "915080371891804634263272761303128298374438082089019628850917" .
    "0691316593175367469551763119843371637221007210577919";
$public_generator = 2;

// if you want it to go fast use smaller values (these are from the
// Diffie Hellman entry on Wikipedia).
//$public_generator = 5;
//$public_prime = 23;

$bob = new Zend_Crypt_DiffieHellman($public_prime, $public_generator);
$alice = new Zend_Crypt_DiffieHellman($public_prime, $public_generator);

// first generate the private key and the public data on both sides
$bob->generateKeys();
$alice->generateKeys();

// you can access the public data using the "getPublicKey" method.
// You can transmit those values over the wire to the other party. 
echo "bob=", $bob->getPublicKey(), PHP_EOL;
echo "alice=", $alice->getPublicKey(), PHP_EOL;

// After both parties have received the public data from the other party
// they can calculate the shared secret:    
echo "shared(alice)=", $alice->computeSecretKey($bob->getPublicKey()), PHP_EOL;
echo "shared(bob  )=", $bob->computeSecretKey($alice->getPublicKey()), PHP_EOL;
// the values should be equal.

The only thing that really is passed over the wire is the return value of Zend_Crypt_DiffieHellman::getPublicKey. The public data can be encoded as text (Zend_Crypt_DiffieHellman::NUMBER) or as binary data (Zend_Crypt_DiffieHellman::BINARY).

There is another one: Zend_Crypt_DiffieHellman::BTWOC which is the same as binary but with a leading zero byte, so the integer is not treated as "signed" integer - if your client application uses the Java JCE or the .NET Crypto API this one is probably the best for binary transfer.

Unsolicited advice

If you want to make your life easier, do not reinvent SSL - just use the existing SSL implementation via HTTPS.

Most SSL libraries allow you to inspect the server certificate so check the validity of your server certificate on the client (at least check the fingerprint).

And if you need or want to you can check the client's certificate on the server (see Using SSL Client Certificates with PHP).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文