ParagonIE\Halite\Symmetric\Crypto::unpackMessageForDecryption PHP Method

unpackMessageForDecryption() public static method

Should return exactly 6 elements.
public static unpackMessageForDecryption ( string $ciphertext ) : array
$ciphertext string
return array
    public static function unpackMessageForDecryption(string $ciphertext) : array
    {
        $length = CryptoUtil::safeStrlen($ciphertext);
        // Fail fast on invalid messages
        if ($length < Halite::VERSION_TAG_LEN) {
            throw new InvalidMessage('Message is too short');
        }
        // The first 4 bytes are reserved for the version size
        $version = CryptoUtil::safeSubstr($ciphertext, 0, Halite::VERSION_TAG_LEN);
        $config = SymmetricConfig::getConfig($version, 'encrypt');
        if ($length < $config->SHORTEST_CIPHERTEXT_LENGTH) {
            throw new InvalidMessage('Message is too short');
        }
        // The salt is used for key splitting (via HKDF)
        $salt = CryptoUtil::safeSubstr($ciphertext, Halite::VERSION_TAG_LEN, $config->HKDF_SALT_LEN);
        // This is the nonce (we authenticated it):
        $nonce = CryptoUtil::safeSubstr($ciphertext, Halite::VERSION_TAG_LEN + $config->HKDF_SALT_LEN, \Sodium\CRYPTO_STREAM_NONCEBYTES);
        // This is the crypto_stream_xor()ed ciphertext
        $encrypted = CryptoUtil::safeSubstr($ciphertext, Halite::VERSION_TAG_LEN + $config->HKDF_SALT_LEN + \Sodium\CRYPTO_STREAM_NONCEBYTES, $length - (Halite::VERSION_TAG_LEN + $config->HKDF_SALT_LEN + \Sodium\CRYPTO_STREAM_NONCEBYTES + $config->MAC_SIZE));
        // $auth is the last 32 bytes
        $auth = CryptoUtil::safeSubstr($ciphertext, $length - $config->MAC_SIZE);
        // We don't need this anymore.
        \Sodium\memzero($ciphertext);
        // Now we return the pieces in a specific order:
        return [$version, $config, $salt, $nonce, $encrypted, $auth];
    }

Usage Example

Beispiel #1
0
 /**
  * @covers Symmetric::unpackMessageForDecryption()
  */
 public function testUnpack()
 {
     $key = new EncryptionKey(new HiddenString(\str_repeat('A', 32)));
     // Randomly sized plaintext
     $size = \Sodium\randombytes_uniform(1023) + 1;
     $plaintext = \Sodium\randombytes_buf($size);
     $message = Symmetric::encrypt(new HiddenString($plaintext), $key, true);
     // Let's unpack our message
     $unpacked = Symmetric::unpackMessageForDecryption($message);
     // Now to test our expected results!
     $this->assertSame(Util::safeStrlen($unpacked[0]), Halite::VERSION_TAG_LEN);
     $this->assertTrue($unpacked[1] instanceof \ParagonIE\Halite\Symmetric\Config);
     $config = $unpacked[1];
     if ($config instanceof \ParagonIE\Halite\Symmetric\Config) {
         $this->assertSame(Util::safeStrlen($unpacked[2]), $config->HKDF_SALT_LEN);
         $this->assertSame(Util::safeStrlen($unpacked[3]), \Sodium\CRYPTO_STREAM_NONCEBYTES);
         $this->assertSame(Util::safeStrlen($unpacked[4]), Util::safeStrlen($message) - (Halite::VERSION_TAG_LEN + $config->HKDF_SALT_LEN + \Sodium\CRYPTO_STREAM_NONCEBYTES + $config->MAC_SIZE));
         $this->assertSame(Util::safeStrlen($unpacked[5]), $config->MAC_SIZE);
     } else {
         $this->fail('Cannot continue');
     }
 }