|
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 | {
|
@@ -134,40 +135,40 @@ public function sendNotifications(array $endpoints, array $payloads = null, arra
|
134 | 135 | * @param string $payload
|
135 | 136 | *
|
136 | 137 | * @return array
|
137 |
| - * |
138 |
| - * @throws |
139 | 138 | */
|
140 | 139 | private function encrypt($userPublicKey, $payload)
|
141 | 140 | {
|
142 |
| - throw new \ErrorException('Encryption does not work yet.'); |
143 |
| - |
144 |
| - // get local curve |
145 |
| - $localCurveGenerator = EccFactory::getNistCurves()->generator256(); |
146 |
| - $localPrivateKey = $localCurveGenerator->createPrivateKey(); |
147 |
| - $localPublicKey = $localPrivateKey->getPublicKey(); |
148 |
| - // var sharedSecret = localCurve.computeSecret(userPublicKey); |
| 141 | + // initialize utilities |
| 142 | + $math = EccFactory::getAdapter(); |
| 143 | + $keySerializer = new UncompressedPointSerializer($math); |
| 144 | + $curveGenerator = EccFactory::getNistCurves()->generator256(); |
| 145 | + $curve = EccFactory::getNistCurves()->curve256(); |
149 | 146 |
|
150 |
| - //var salt = crypto.randomBytes(16); |
| 147 | + // get local key pair |
| 148 | + $localPrivateKeyObject = $curveGenerator->createPrivateKey(); |
| 149 | + $localPublicKeyObject = $localPrivateKeyObject->getPublicKey(); |
| 150 | + $localPublicKey = base64_encode(hex2bin($keySerializer->serialize($localPublicKeyObject->getPoint()))); |
151 | 151 |
|
152 |
| - //ece.saveKey('webpushKey', sharedSecret); |
| 152 | + // get user public key object |
| 153 | + $userPublicKeyObject = new PublicKey($math, $curveGenerator, $keySerializer->unserialize($curve, bin2hex(base64_decode($userPublicKey)))); |
153 | 154 |
|
154 |
| - /*var cipherText = ece.encrypt(payload, { |
155 |
| - keyid: 'webpushKey', |
156 |
| - salt: urlBase64.encode(salt), |
157 |
| - });*/ |
| 155 | + // get shared secret from user public key and local private key |
| 156 | + $sharedSecret = $userPublicKeyObject->getPoint()->mul($localPrivateKeyObject->getSecret())->getX(); |
158 | 157 |
|
159 |
| - $messages = new MessageFactory(EccFactory::getAdapter()); |
160 |
| - $message = $messages->plaintext($payload, 'sha256'); |
| 158 | + // generate salt |
| 159 | + $salt = openssl_random_pseudo_bytes(16); |
161 | 160 |
|
162 |
| - $dh = $localPrivateKey->createExchange($messages, $userPublicKey); |
163 |
| - $salt = hash('sha256', $dh->calculateSharedKey(), true); |
| 161 | + // get encryption key |
| 162 | + $encryptionKey = hash_hmac('sha256', $salt, $sharedSecret); |
164 | 163 |
|
165 |
| - $cipherText = $dh->encrypt($message)->getContent(); |
| 164 | + // encrypt |
| 165 | + $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-128-gcm')); |
| 166 | + $cipherText = openssl_encrypt($payload, 'aes-128-gcm', $encryptionKey, false, $iv); // base 64 encoded |
166 | 167 |
|
167 | 168 | return array(
|
168 |
| - 'localPublicKey' => base64_encode($localPublicKey), |
| 169 | + 'localPublicKey' => $localPublicKey, |
169 | 170 | 'salt' => base64_encode($salt),
|
170 |
| - 'cipherText' => base64_encode($cipherText), |
| 171 | + 'cipherText' => $cipherText, |
171 | 172 | );
|
172 | 173 | }
|
173 | 174 |
|
|
0 commit comments