Skip to content

Instantly share code, notes, and snippets.

@ksg91
Created November 11, 2020 06:03
Show Gist options
  • Save ksg91/0a01b35693b7cc8157984973767937fc to your computer and use it in GitHub Desktop.
Save ksg91/0a01b35693b7cc8157984973767937fc to your computer and use it in GitHub Desktop.
Diffie-Hillman key exchange and encryption implemetation in PHP
<?php
class Encryption
{
public const ALGORITHM = "ECDH";
public const CURVE = "curve25519";
public static function encrypt($sInput, $oSenderPrivateKey, $receiverPublicKey, $randomKeySender, $randomKeyReceiver)
{
$xorOfRandoms = self::XorOfRandom($randomKeySender, $randomKeyReceiver);
$encryptionKey = self::generateEncryptionKey($xorOfRandoms, $oSenderPrivateKey, $receiverPublicKey);
$iv = substr($xorOfRandoms, 0, -12);
global $tag;
$sResult = openssl_encrypt($sInput, 'aes-256-gcm', $encryptionKey, 0, $iv, $tag);
return $sResult;
}
public static function decrypt($sInput, $oReceiverPrivateKey, $senderPublicKey, $randomKeySender, $randomKeyReceiver)
{
$xorOfRandoms = self::XorOfRandom($randomKeySender, $randomKeyReceiver);
$encryptionKey = self::generateEncryptionKey($xorOfRandoms, $oReceiverPrivateKey, $senderPublicKey);
$iv = substr($xorOfRandoms, 0, -12);
global $tag;
$sResult = openssl_decrypt($sInput, 'aes-256-gcm', $encryptionKey, 0, $iv, $tag);
return $sResult;
}
public static function generateEncryptionKey($xorOfRandoms, $oPrivateKey, $sPublicKey)
{
$sPrivateKey = openssl_pkey_get_private($oPrivateKey);
$sSharedKey = openssl_dh_compute_key(base64_decode($sPublicKey), $sPrivateKey);
$salt = substr($xorOfRandoms, 0, 20);
$encryptionKey = hash_hkdf('sha256', $sSharedKey, 32, 'aes-256-gcm', $salt);
return $encryptionKey;
}
public static function generateKey()
{
$configargs = array();
$configargs['p'] = hex2bin('00a3251e733f44b92beef49d9f376a4bfd1dbdf4afdac810775941c65f73d2882939cd1c5fc39f0f22d29c20c1e4c01803b8b6d8daad3b39a6da8efe1230e9035d22baef18d27b69f95bcb78c60c8c6bf24992c249e0457772b3553630f2401789185003fa2d547a7f344c7332b688145114be805795e6a3f651ff17474f15d60e6c4753722c2a4c21cb7df34997c9475e40337b99527e7af3522780de1b266b40bb14110bfbe6d82fcfa0062f96b91c0bb4cbd3a6629c4867f681f2c6ff45030a9d679dce27d96b485dcafbc25d849b8bcb40c7a40c8a6ef4abbab610c3b8254dcf6096f4dbe8001c58477afb5186d122d74e94317ad5da3d53dedabb648d626b');
$configargs['g'] = hex2bin('02');
return openssl_pkey_new([
'curve' => Encryption::CURVE,
'digest_alg' => Encryption::ALGORITHM,
'dh' => $configargs
]);
}
public function XorOfRandom($randomKeySender, $randomKeyReceiver)
{
$result = base64_decode($randomKeySender) xor base64_decode($randomKeyReceiver);
return base64_encode($result);
}
}
$oReceiversKeyPair = Encryption::generateKey();
$sReceiversPublicKey = openssl_pkey_get_details($oReceiversKeyPair);
$oSendersKeyPair = Encryption::generateKey();
$sSendersPublicKey = openssl_pkey_get_details($oSendersKeyPair);
$receiverPublicKey = base64_encode($sReceiversPublicKey['dh']['pub_key']);
$senderPublicKey = base64_encode($sSendersPublicKey['dh']['pub_key']);
var_dump("receiverPublicKey:", $receiverPublicKey);
var_dump("senderPublicKey:", $senderPublicKey);
$randomKeySender = base64_encode(random_bytes(32));
$randomKeyReceiver = base64_encode(random_bytes(32));
var_dump("randomKeySender:", $randomKeySender);
var_dump("randomKeyReceiver:", $randomKeyReceiver);
$sDataToTest = "test data goes here";
($sEncrypted = Encryption::encrypt(
$sDataToTest,
$oSendersKeyPair,
$receiverPublicKey,
$randomKeySender,
$randomKeyReceiver
));
var_dump("sEncrypted:", $sEncrypted);
($sDecrypted = Encryption::decrypt(
$sEncrypted,
$oReceiversKeyPair,
$senderPublicKey,
$randomKeySender,
$randomKeyReceiver
));
var_dump("sDecrypted:", $sDecrypted);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment