|
16 | 16 | use Buzz\Client\MultiCurl;
|
17 | 17 | use Buzz\Exception\RequestException;
|
18 | 18 | use Buzz\Message\Response;
|
| 19 | +use Mdanter\Ecc\Crypto\Key\PublicKey; |
19 | 20 | use Mdanter\Ecc\EccFactory;
|
20 |
| -use Mdanter\Ecc\Message\MessageFactory; |
| 21 | +use Mdanter\Ecc\Serializer\Point\UncompressedPointSerializer; |
21 | 22 |
|
22 | 23 | class WebPush
|
23 | 24 | {
|
@@ -139,35 +140,37 @@ public function sendNotifications(array $endpoints, array $payloads = null, arra
|
139 | 140 | */
|
140 | 141 | private function encrypt($userPublicKey, $payload)
|
141 | 142 | {
|
142 |
| - throw new \ErrorException('Encryption does not work yet.'); |
| 143 | + // initialize utilities |
| 144 | + $math = EccFactory::getAdapter(); |
| 145 | + $keySerializer = new UncompressedPointSerializer($math); |
| 146 | + $curveGenerator = EccFactory::getNistCurves()->generator256(); |
| 147 | + $curve = EccFactory::getNistCurves()->curve256(); |
143 | 148 |
|
144 |
| - // get local curve |
145 |
| - $localCurveGenerator = EccFactory::getNistCurves()->generator256(); |
146 |
| - $localPrivateKey = $localCurveGenerator->createPrivateKey(); |
147 |
| - $localPublicKey = $localPrivateKey->getPublicKey(); |
148 |
| - // var sharedSecret = localCurve.computeSecret(userPublicKey); |
| 149 | + // get local key pair |
| 150 | + $localPrivateKeyObject = $curveGenerator->createPrivateKey(); |
| 151 | + $localPublicKeyObject = $localPrivateKeyObject->getPublicKey(); |
| 152 | + $localPublicKey = base64_encode(hex2bin($keySerializer->serialize($localPublicKeyObject->getPoint()))); |
149 | 153 |
|
150 |
| - //var salt = crypto.randomBytes(16); |
| 154 | + // get user public key object |
| 155 | + $userPublicKeyObject = new PublicKey($math, $curveGenerator, $keySerializer->unserialize($curve, bin2hex(base64_decode($userPublicKey)))); |
151 | 156 |
|
152 |
| - //ece.saveKey('webpushKey', sharedSecret); |
| 157 | + // get shared secret from user public key and local private key |
| 158 | + $sharedSecret = $userPublicKeyObject->getPoint()->mul($localPrivateKeyObject->getSecret())->getX(); |
153 | 159 |
|
154 |
| - /*var cipherText = ece.encrypt(payload, { |
155 |
| - keyid: 'webpushKey', |
156 |
| - salt: urlBase64.encode(salt), |
157 |
| - });*/ |
| 160 | + // generate salt |
| 161 | + $salt = base64_encode(openssl_random_pseudo_bytes(16)); |
158 | 162 |
|
159 |
| - $messages = new MessageFactory(EccFactory::getAdapter()); |
160 |
| - $message = $messages->plaintext($payload, 'sha256'); |
| 163 | + // get encryption key |
| 164 | + $encryptionKey = hash_hmac('sha256', $salt, $sharedSecret); |
161 | 165 |
|
162 |
| - $dh = $localPrivateKey->createExchange($messages, $userPublicKey); |
163 |
| - $salt = hash('sha256', $dh->calculateSharedKey(), true); |
164 |
| - |
165 |
| - $cipherText = $dh->encrypt($message)->getContent(); |
| 166 | + // encrypt |
| 167 | + $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-128-gcm')); |
| 168 | + $cipherText = openssl_encrypt($payload, 'aes-128-gcm', $encryptionKey, false, $iv); // base 64 encoded |
166 | 169 |
|
167 | 170 | return array(
|
168 |
| - 'localPublicKey' => base64_encode($localPublicKey), |
169 |
| - 'salt' => base64_encode($salt), |
170 |
| - 'cipherText' => base64_encode($cipherText), |
| 171 | + 'localPublicKey' => $localPublicKey, |
| 172 | + 'salt' => $salt, |
| 173 | + 'cipherText' => $cipherText, |
171 | 174 | );
|
172 | 175 | }
|
173 | 176 |
|
|
0 commit comments