3

Zend_Crypt_DiffieHellmanクラスの使用例はありますか?ZendFramework上のPHPサーバーと安全に通信するデスクトップアプリケーションを作成しようとしています。2つのパーティ間で共有キーを確立する方法を理解するのに苦労しています。自分の素数のセットを取得する必要がありますか?

これを使用して共有キーを取得する方法の例をいただければ幸いです。

私の本当の質問は、素数とそのジェネレーターを取得する方法だと思います。

4

1 に答える 1

4

グループを取得する方法(素数とジェネレーターで構成されます)

私は決して暗号化の専門家ではありませんが、RFC 2412で定義されている「既知のグループ」(OAKLEYキー決定プロトコル(付録E.1)またはRFC 3526のグループ)を使用する必要があると思います。で使用する前に、まず16進数を10進数に変換する必要がありますZend_Crypt_DiffieHellman

どのグループを使用する必要がありますか?

大きいほど良い-いいえ、冗談です。

鍵交換の実装方法によって異なります。HTTPリクエストごとにDH交換を実行する必要がある場合、計算に時間がかかるため、グループが大きくなるとサーバーが強制終了されます(ただし、クラックが難しくなります)。私の例では、768ビットの「WellKnown Group 1」を使用しましたが、かなり低速でした(私の開発マシンは最速ではありません)。

サーバーとクライアントが、どの事前定義されたグループを使用するかについての最初のステップで合意するオプションを追加することもできます。例:アプリケーションで、よく知られているグループ1、2、および5を配信します。そして、実際のDHキー交換の前に、当事者は実際のDHキー交換にグループ1を使用することに同意します。そうすれば、ハードウェアが追いついたときに、より大きなグループに切り替えることができます。もちろん、このグループ契約は、鍵交換プロセスに別のステップを追加します。

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::getPublicKeyZend_Crypt_DiffieHellman::NUMBERパブリックデータは、テキスト( )またはバイナリデータ()としてエンコードできますZend_Crypt_DiffieHellman::BINARY

もう1つあります。Zend_Crypt_DiffieHellman::BTWOCこれはバイナリと同じですが、先行ゼロバイトがあるため、整数は「符号付き」整数として扱われません。クライアントアプリケーションがJavaJCEまたは.NETCrypto APIを使用している場合、これがおそらく最適です。バイナリ転送用。

未承諾のアドバイス

生活を楽にしたい場合は、SSLを再発明しないでください。HTTPS経由で既存のSSL実装を使用するだけです。

ほとんどのSSLライブラリではサーバー証明書を検査できるため、クライアントでサーバー証明書の有効性を確認してください(少なくともフィンガープリントを確認してください)。

また、必要な場合、または必要な場合は、サーバー上のクライアントの証明書を確認できます(PHPでのSSLクライアント証明書の使用を参照)。

于 2012-02-08T10:56:36.910 に答える