First generate a public/private DH keypair locally, and have
the remote party do the same. We need to use the openssl
command-line utility.
# generate private/public key keypair
openssl dhparam -out dhparam.pem 2048
openssl genpkey -paramfile dhparam.pem -out privatekey.pem
# extract public key only
openssl pkey -in privatekey.pem -pubout -out publickey.pem
Next, send your public key to the remote party. Use the openssl
pkey command to view the public key you will be sent from
the remote party.
openssl pkey -pubin -in remotepublickey.pem -text -noout
The above example will output
something similar to:
PKCS#3 DH Public-Key: (2048 bit)
public-key:
67:e5:e5:fa:e0:7b:0f:96:2c:dc:96:44:5f:50:02:
9e:8d:c2:6c:04:68:b0:d1:1d:75:66:fc:63:f5:e3:
42:30:b8:96:c1:45:cc:08:60:b4:21:3b:dd:ee:66:
88:db:77:d9:1e:11:89:d4:5c:f2:7a:f2:f1:fe:1c:
77:9d:6f:13:b8:b2:56:00:ef:cb:3b:60:79:74:02:
98:f5:f9:8e:3e:b5:62:08:de:ca:8c:c3:40:4a:80:
79:d5:43:06:17:a8:19:56:af:cc:95:5e:e2:32:2d:
d2:14:7b:76:5a:9a:f1:3c:76:76:35:cc:7b:c1:a5:
f4:39:e5:b6:ca:71:3f:7c:3f:97:e5:ab:86:c1:cd:
0e:e6:ee:04:c9:e6:2d:80:7e:59:c0:49:eb:b6:64:
4f:a8:f9:bb:a3:87:b3:3d:76:01:9e:2b:16:94:a4:
37:30:fb:35:e2:63:be:23:90:b9:ef:3f:46:46:04:
94:8f:60:79:7a:51:55:d6:1a:1d:f5:d9:7f:4a:3e:
aa:ac:b0:d0:82:cc:c2:e0:94:e0:54:c1:17:83:0b:
74:08:4d:5a:79:ae:ff:7f:1c:04:ab:23:39:4a:ae:
87:83:55:43:ab:7a:7c:04:9d:20:80:bb:af:5f:16:
a3:e3:20:b9:21:47:8c:f8:7f:a8:60:80:9e:61:77:
36
[...abbreviated...]
Use this public key as a parameter to openssl_dh_compute_key()
in order to compute the shared secret.
<?php
$remote_public_key = '67e5e5fae07b0f962cdc96445f50029e8dc26c0468b0d11d7566fc63f5e34230b896c145cc0860b4213bddee6688db77d91e1189d45cf27af2f1fe1c779d6f13b8b25600efcb3b6079740298f5f98e3eb56208deca8cc3404a8079d5430617a81956afcc955ee2322dd2147b765a9af13c767635cc7bc1a5f439e5b6ca713f7c3f97e5ab86c1cd0ee6ee04c9e62d807e59c049ebb6644fa8f9bba387b33d76019e2b1694a43730fb35e263be2390b9ef3f464604948f60797a5155d61a1df5d97f4a3eaaacb0d082ccc2e094e054c117830b74084d5a79aeff7f1c04ab23394aae87835543ab7a7c049d2080bbaf5f16a3e320b921478cf87fa860809e617736';
$local_priv_key = openssl_pkey_get_private('file://privatekey.pem');
$shared_secret = openssl_dh_compute_key(hex2bin($remote_public_key), $local_priv_key);
echo bin2hex($shared_secret)."\n";
?>