Beispiel #1
1
 /**
  *  {@inheritdoc}
  */
 public function decryptContent($data, $cek, $iv, $aad, $encoded_protected_header, $tag)
 {
     $calculated_aad = $encoded_protected_header;
     if (null !== $aad) {
         $calculated_aad .= '.' . $aad;
     }
     if (version_compare(PHP_VERSION, '7.1.0') >= 0) {
         return openssl_decrypt($data, $this->getMode($cek), $cek, OPENSSL_RAW_DATA, $iv, $tag, $calculated_aad);
     } elseif (class_exists('\\Crypto\\Cipher')) {
         $cipher = Cipher::aes(Cipher::MODE_GCM, $this->getKeySize());
         $cipher->setTag($tag);
         $cipher->setAAD($calculated_aad);
         $plaintext = $cipher->decrypt($data, $cek, $iv);
         return $plaintext;
     }
     return GCM::decrypt($cek, $iv, $data, $calculated_aad, $tag);
 }
Beispiel #2
0
 /**
  * {@inheritdoc}
  */
 public function unwrapKey(JWKInterface $key, $encrypted_cek, array $header)
 {
     $this->checkKey($key);
     $this->checkAdditionalParameters($header);
     $kek = Base64Url::decode($key->get('k'));
     $tag = Base64Url::decode($header['tag']);
     $iv = Base64Url::decode($header['iv']);
     if (version_compare(PHP_VERSION, '7.1.0') >= 0) {
         return openssl_decrypt($encrypted_cek, $this->getMode($kek), $kek, OPENSSL_RAW_DATA, $iv, $tag, null);
     } elseif (class_exists('\\Crypto\\Cipher')) {
         $cipher = Cipher::aes(Cipher::MODE_GCM, $this->getKeySize());
         $cipher->setTag($tag);
         $cipher->setAAD(null);
         $cek = $cipher->decrypt($encrypted_cek, $kek, $iv);
         return $cek;
     }
     return AESGCM::decrypt($kek, $iv, $encrypted_cek, null, $tag);
 }
Beispiel #3
0
 /**
  * @param string $payload          With padding
  * @param string $userPublicKey    Base 64 encoded (MIME or URL-safe)
  * @param string $userAuthToken    Base 64 encoded (MIME or URL-safe)
  * @param bool   $nativeEncryption Use OpenSSL (>PHP7.1)
  *
  * @return array
  */
 public static function encrypt($payload, $userPublicKey, $userAuthToken, $nativeEncryption)
 {
     $userPublicKey = Base64Url::decode($userPublicKey);
     $userAuthToken = Base64Url::decode($userAuthToken);
     // initialize utilities
     $math = EccFactory::getAdapter();
     $pointSerializer = new UncompressedPointSerializer($math);
     $generator = EccFactory::getNistCurves()->generator256();
     $curve = EccFactory::getNistCurves()->curve256();
     // get local key pair
     $localPrivateKeyObject = $generator->createPrivateKey();
     $localPublicKeyObject = $localPrivateKeyObject->getPublicKey();
     $localPublicKey = hex2bin($pointSerializer->serialize($localPublicKeyObject->getPoint()));
     // get user public key object
     $pointUserPublicKey = $pointSerializer->unserialize($curve, bin2hex($userPublicKey));
     $userPublicKeyObject = $generator->getPublicKeyFrom($pointUserPublicKey->getX(), $pointUserPublicKey->getY(), $generator->getOrder());
     // get shared secret from user public key and local private key
     $sharedSecret = hex2bin($math->decHex(gmp_strval($userPublicKeyObject->getPoint()->mul($localPrivateKeyObject->getSecret())->getX())));
     // generate salt
     $salt = openssl_random_pseudo_bytes(16);
     // section 4.3
     $ikm = !empty($userAuthToken) ? self::hkdf($userAuthToken, $sharedSecret, 'Content-Encoding: auth' . chr(0), 32) : $sharedSecret;
     // section 4.2
     $context = self::createContext($userPublicKey, $localPublicKey);
     // derive the Content Encryption Key
     $contentEncryptionKeyInfo = self::createInfo('aesgcm', $context);
     $contentEncryptionKey = self::hkdf($salt, $ikm, $contentEncryptionKeyInfo, 16);
     // section 3.3, derive the nonce
     $nonceInfo = self::createInfo('nonce', $context);
     $nonce = self::hkdf($salt, $ikm, $nonceInfo, 12);
     // encrypt
     // "The additional data passed to each invocation of AEAD_AES_128_GCM is a zero-length octet sequence."
     if (!$nativeEncryption) {
         list($encryptedText, $tag) = \AESGCM\AESGCM::encrypt($contentEncryptionKey, $nonce, $payload, '');
     } else {
         $encryptedText = openssl_encrypt($payload, 'aes-128-gcm', $contentEncryptionKey, OPENSSL_RAW_DATA, $nonce, $tag);
         // base 64 encoded
     }
     // return values in url safe base64
     return array('localPublicKey' => Base64Url::encode($localPublicKey), 'salt' => Base64Url::encode($salt), 'cipherText' => $encryptedText . $tag);
 }
Beispiel #4
0
 public static function decrypt($encData, $password, $IV, $AAD)
 {
     /*
      * https://tools.ietf.org/html/rfc5116#section-5.1
      * 
      * An authentication tag with a length of 16 octets (128
      * bits) is used.  The AEAD_AES_128_GCM ciphertext is formed by
      * appending the authentication tag provided as an output to the GCM
      * encryption operation to the ciphertext that is output by that
      * operation. 
      *
      * ciphertext is exactly 16 octets longer than its
      * corresponding plaintext.
      */
     if (strlen($encData) < self::TAG_LEN) {
         return false;
     }
     // Get the tag appended to cipher text
     $tag = substr($encData, strlen($encData) - self::TAG_LEN, self::TAG_LEN);
     // Resize the cipher text
     $encData = substr($encData, 0, strlen($encData) - self::TAG_LEN);
     if (self::useOpenSSL()) {
         $method = self::getMethod($password);
         $data = openssl_decrypt($encData, $method, $password, OPENSSL_RAW_DATA, $IV, $tag, $AAD);
     } else {
         if (self::useSO()) {
             try {
                 $cipher = \Crypto\Cipher::aes(\Crypto\Cipher::MODE_GCM, self::bitLen($password));
                 $cipher->setTag($tag);
                 $cipher->setAAD($AAD);
                 $data = $cipher->decrypt($encData, $password, $IV);
             } catch (\Exception $e) {
                 return false;
             }
         } else {
             try {
                 $data = AESGCM::decrypt($password, $IV, $encData, $AAD, $tag);
             } catch (\Exception $e) {
                 //echo $e->getMessage();
                 return false;
             }
         }
     }
     return $data;
 }