/** * See Key::generate() * * @param type $type * @param type $secret_key */ public static function generate($type = self::CRYPTO_BOX, &$secret_key = null) { if ($type & self::ASYMMETRIC === 0) { $type &= self::ASYMMETRIC; } return parent::generate($type, $secret_key); }
public function __construct($file, Key $key = null) { if (is_string($file)) { $this->fp = \fopen($file, 'rb'); $this->closeAfter = true; $this->pos = 0; $this->stat = \fstat($this->fp); } elseif (is_resource($file)) { $this->fp = $file; $this->pos = \ftell($this->fp); $this->stat = \fstat($this->fp); } else { throw new \ParagonIE\Halite\Alerts\InvalidType('Argument 1: Expected a filename or resource'); } $this->hashKey = !empty($key) ? $key->getRawKeyMaterial() : ''; $this->hash = $this->getHash(); }
public function testSeal() { \touch(__DIR__ . '/tmp/paragon_avatar.sealed.png'); \chmod(__DIR__ . '/tmp/paragon_avatar.sealed.png', 0777); \touch(__DIR__ . '/tmp/paragon_avatar.opened.png'); \chmod(__DIR__ . '/tmp/paragon_avatar.opened.png', 0777); list($secretkey, $publickey) = Key::generate(Key::CRYPTO_BOX); File::sealFile(__DIR__ . '/tmp/paragon_avatar.png', __DIR__ . '/tmp/paragon_avatar.sealed.png', $publickey); File::unsealFile(__DIR__ . '/tmp/paragon_avatar.sealed.png', __DIR__ . '/tmp/paragon_avatar.opened.png', $secretkey); $this->assertEquals(\hash_file('sha256', __DIR__ . '/tmp/paragon_avatar.png'), \hash_file('sha256', __DIR__ . '/tmp/paragon_avatar.opened.png')); }
/** * See Key::generate() * * @param type $type * @param type $secret_key */ public static function generate($type = self::CRYPTO_SECRETBOX, &$secret_key = null) { if ($type & self::ASYMMETRIC !== 0) { $type ^= self::ASYMMETRIC; } if ($type & self::PUBLIC_KEY !== 0) { $type ^= self::PUBLIC_KEY; } // Force secret key $type &= self::SECRET_KEY; return parent::generate($type, $secret_key); }
/** * Generate a keypair * * @param array $type */ public static function generateKeys($type = Key::CRYPTO_BOX) { if ($type & Key::ASYMMETRIC === 0) { throw new CryptoAlert\InvalidFlags(); } switch ($type) { case Key::ENCRYPTION: case Key::SIGNATURE: case Key::CRYPTO_SIGN: case Key::CRYPTO_BOX: $keys = Key::generate($type); return new KeyPair(...$keys); default: throw new CryptoAlert\InvalidKey(); } }
public function testSealFail() { \touch(__DIR__ . '/tmp/paragon_avatar.seal_fail.png'); \chmod(__DIR__ . '/tmp/paragon_avatar.seal_fail.png', 0777); \touch(__DIR__ . '/tmp/paragon_avatar.open_fail.png'); \chmod(__DIR__ . '/tmp/paragon_avatar.open_fail.png', 0777); list($secretkey, $publickey) = Key::generate(Key::CRYPTO_BOX); File::sealFile(__DIR__ . '/tmp/paragon_avatar.png', __DIR__ . '/tmp/paragon_avatar.seal_fail.png', $publickey); $fp = \fopen(__DIR__ . '/tmp/paragon_avatar.seal_fail.png', 'ab'); \fwrite($fp, \Sodium\randombytes_buf(1)); fclose($fp); try { File::unsealFile(__DIR__ . '/tmp/paragon_avatar.seal_fail.png', __DIR__ . '/tmp/paragon_avatar.opened.png', $secretkey); throw new \Exception('ERROR: THIS SHOULD ALWAYS FAIL'); } catch (CryptoException\InvalidMessage $e) { $this->assertTrue($e instanceof CryptoException\InvalidMessage); } }
/** * Generate a new keypair * * @param int $type Key flags * @param &string $secret_key - Reference to optional variable to store secret key in * @return KeyPair * @throws CryptoException\InvalidKey */ public static function generate($type = Key::CRYPTO_SIGN, &$secret_key = null) { if (Key::doesNotHaveFlag($type, Key::ASYMMETRIC)) { throw new CryptoException\InvalidKey('An asymmetric key type must be passed to KeyPair::generate()'); } if (Key::hasFlag($type, Key::SIGNATURE)) { $key = SignatureSecretKey::generate(Key::CRYPTO_SIGN, $secret_key); $keypair = new SignatureKeyPair(...$key); return $keypair; } throw new CryptoException\InvalidKey('You must specify encryption or authentication flags.'); }
/** * @param HiddenString $keyMaterial - The actual key data */ public function __construct(HiddenString $keyMaterial) { parent::__construct($keyMaterial); $this->isAsymmetricKey = true; $this->isPublicKey = true; }
/** * Seal a (file handle) * * @param $input * @param $output * @param \ParagonIE\Halite\Contract\CryptoKeyInterface $publickey */ public static function sealResource($input, $output, \ParagonIE\Halite\Contract\CryptoKeyInterface $publickey) { // Input validation if (!\is_resource($input)) { throw new \ParagonIE\Halite\Alerts\InvalidType('Expected input handle to be a resource'); } if (!\is_resource($output)) { throw new \ParagonIE\Halite\Alerts\InvalidType('Expected output handle to be a resource'); } if (!$publickey->isPublicKey()) { throw new CryptoAlert\InvalidKey('Especter a public key'); } if (!$publickey->isAsymmetricKey()) { throw new CryptoAlert\InvalidKey('Expected a key intended for asymmetric-key cryptography'); } // Generate a new keypair for this encryption list($eph_secret, $eph_public) = Key::generate(Key::CRYPTO_BOX); // Calculate the shared secret key $key = Asymmetric::getSharedSecret($eph_secret, $publickey, true); // Destroy the secre tkey after we have the shared secret unset($eph_secret); $config = self::getConfig(Halite::HALITE_VERSION, 'seal'); // Generate a nonce as per crypto_box_seal $nonce = \Sodium\crypto_generichash($eph_public->get() . $publickey->get(), null, \Sodium\CRYPTO_STREAM_NONCEBYTES); // Generate a random HKDF salt $hkdfsalt = \Sodium\randombytes_buf($config['HKDF_SALT_LEN']); // Split the keys list($encKey, $authKey) = self::splitKeys($key, $hkdfsalt); // We no longer need the original key after we split it unset($key); $mac = \hash_init('sha256', HASH_HMAC, $authKey); // We no longer need to retain this after we've set up the hash context unset($authKey); $written = \fwrite($output, Halite::HALITE_VERSION, Halite::VERSION_TAG_LEN); if ($written === false) { throw new FileAlert\AccessDenied('Could not write to the file'); } $written &= \fwrite($output, $eph_public->get(), \Sodium\CRYPTO_BOX_PUBLICKEYBYTES); if ($written === false) { throw new FileAlert\AccessDenied('Could not write to the file'); } $written &= \fwrite($output, $hkdfsalt, Halite::HKDF_SALT_LEN); if ($written === false) { throw new FileAlert\AccessDenied('Could not write to the file'); } \hash_update($mac, Halite::HALITE_VERSION); \hash_update($mac, $eph_public->get()); \hash_update($mac, $hkdfsalt); unset($eph_public); return self::streamEncrypt($input, $output, new Key($encKey), $nonce, $mac, $config); }
public function testDerive() { $key = Key::deriveFromPassword('apple', "\t\n\v\f\r" . ""); $this->assertEquals($key->get(), "6¦Â¹je\r€¿~^XóÖ" . "63•uÞû7¥B½TX-"); }
/** * Save a key to a file * * @param Key|KeyPair $key * @param string $filename * @return int|boolean */ public static function save($key, $filename = '') { if ($key instanceof KeyPair) { return self::saveKeyFile($filename, $key->getSecretKey()->get()); } return self::saveKeyFile($filename, $key->get()); }
public function testDerive() { $key = Key::deriveFromPassword('apple', "\t\n\v\f\r" . ""); $this->assertEquals($key->get(), "6�¹je\r��~^X��" . "63�u��7�B�TX-"); }
/** * Save a key to a file * * @param Key|KeyPair $key * @param string $filename * @return bool */ public static function save($key, string $filename = '') : bool { if ($key instanceof KeyPair) { return self::saveKeyFile($filename, $key->getSecretKey()->getRawKeyMaterial()); } return self::saveKeyFile($filename, $key->getRawKeyMaterial()); }
/** * Load a keypair from a file * * @param string $filePath * @param int $type * @return KeyPair * * @throws CryptoException\InvalidFlags */ public static function fromFile($filePath, $type = Key::CRYPTO_BOX) { $keys = Key::fromFile($filePath, $type | Key::ASYMMETRIC | Key::ENCRYPTION); return new KeyPair(...$keys); }
/** * Generate a new keypair * * @param int $type Key flags * @return array [Key $secret, Key $public] * @throws CryptoAlert\InvalidKey */ public static function generate($type = Key::CRYPTO_BOX) { if (($type & Key::ASYMMETRIC) === 0) { throw new CryptoAlert\InvalidKey('An asymmetric key type must be passed to KeyPair::generate()'); } if (($type & Key::ENCRYPTION) !== 0) { return Key::generate(Key::CRYPTO_BOX); } elseif (($type & Key::SIGNATURE) !== 0) { return Key::generate(Key::CRYPTO_SIGN); } throw new CryptoAlert\InvalidKey('You must specify encryption or authentication flags.'); }
/** * Split a key using a variant of HKDF that used a keyed BLAKE2b hash rather * than an HMAC construct * * @param \ParagonIE\Halite\Key $master * @param string $salt * @return array */ public static function splitKeys(Key $master, $salt = null) { $binary = $master->get(); return [CryptoUtil::hkdfBlake2b($binary, \Sodium\CRYPTO_SECRETBOX_KEYBYTES, Config::HKDF_SBOX, $salt), CryptoUtil::hkdfBlake2b($binary, \Sodium\CRYPTO_AUTH_KEYBYTES, Config::HKDF_AUTH, $salt)]; }
/** * @param string $keyMaterial - The actual key data * @param bool $signing - Is this a signing key? */ public function __construct($keyMaterial = '', ...$args) { $signing = \count($args) >= 1 ? $args[0] : false; parent::__construct($keyMaterial, false, $signing, false); }
/** * Split a key using HKDF * * @param Key $master * @param string $salt * @param Config $config * @return string[] */ protected static function splitKeys(Key $master, string $salt = '', Config $config = null) : array { $binary = $master->getRawKeyMaterial(); return [Util::hkdfBlake2b($binary, \Sodium\CRYPTO_SECRETBOX_KEYBYTES, $config->HKDF_SBOX, $salt), Util::hkdfBlake2b($binary, \Sodium\CRYPTO_AUTH_KEYBYTES, $config->HKDF_AUTH, $salt)]; }