/** * Verify a signed message with the correct public key * * @param string $message Message to verify * @param SignaturePublicKey $publicKey * @param string $signature * @param boolean $raw Don't hex decode the input? * @return bool * @throws CryptoException\InvalidSignature */ public static function verify(string $message, SignaturePublicKey $publicKey, string $signature, bool $raw = false) : bool { if (!$raw) { $signature = \Sodium\hex2bin($signature); } if (CryptoUtil::safeStrlen($signature) !== \Sodium\CRYPTO_SIGN_BYTES) { throw new CryptoException\InvalidSignature('Signature is not the correct length; is it encoded?'); } return \Sodium\crypto_sign_verify_detached($signature, $message, $publicKey->getRawKeyMaterial()); }
/** * Derive a key pair for public key signatures from a password and salt * * @param string $password * @param string $salt * @param bool $legacy Use scrypt? * * @return SignatureKeyPair * @throws CryptoException\InvalidSalt */ public static function deriveSignatureKeyPair(string $password, string $salt, bool $legacy = false) : SignatureKeyPair { if ($legacy) { if (CryptoUtil::safeStrlen($salt) !== \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES) { throw new CryptoException\InvalidSalt('Expected ' . \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES . ' bytes, got ' . CryptoUtil::safeStrlen($salt)); } // Digital signature keypair $seed = \Sodium\crypto_pwhash_scryptsalsa208sha256(\Sodium\CRYPTO_SIGN_SEEDBYTES, $password, $salt, \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE, \Sodium\CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE); } else { if (CryptoUtil::safeStrlen($salt) !== \Sodium\CRYPTO_PWHASH_SALTBYTES) { throw new CryptoException\InvalidSalt('Expected ' . \Sodium\CRYPTO_PWHASH_SALTBYTES . ' bytes, got ' . CryptoUtil::safeStrlen($salt)); } // Digital signature keypair $seed = \Sodium\crypto_pwhash(\Sodium\CRYPTO_SIGN_SEEDBYTES, $password, $salt, \Sodium\CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE, \Sodium\CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE); } $keypair = \Sodium\crypto_sign_seed_keypair($seed); $secret_key = \Sodium\crypto_sign_secretkey($keypair); // Let's wipe our $kp variable \Sodium\memzero($keypair); return new SignatureKeyPair(new SignatureSecretKey($secret_key)); }
/** * Verify a MAC * * @param string $mac * @param string $message * @param string $aKey * @return bool * @throws CryptoException\InvalidSignature */ protected static function verifyMAC(string $mac, string $message, string $aKey) : bool { if (CryptoUtil::safeStrlen($mac) !== \Sodium\CRYPTO_AUTH_BYTES) { throw new CryptoException\InvalidSignature('Message Authentication Code is not the correct length; is it encoded?'); } return \Sodium\crypto_auth_verify($mac, $message, $aKey); }
/** * Verify a Message Authentication Code (MAC) of a message, with a shared * key. * * @param string $mac Message Authentication Code * @param string $message The message to verify * @param string $authKey Authentication key (symmetric) * @param SymmetricConfig $config Configuration object * @return bool * @throws InvalidMessage * @throws InvalidSignature */ protected static function verifyMAC(string $mac, string $message, string $authKey, SymmetricConfig $config) : bool { if (CryptoUtil::safeStrlen($mac) !== $config->MAC_SIZE) { throw new InvalidSignature('Argument 1: Message Authentication Code is not the correct length; is it encoded?'); } if ($config->MAC_ALGO === 'BLAKE2b') { $calc = \Sodium\crypto_generichash($message, $authKey, $config->MAC_SIZE); $res = \hash_equals($mac, $calc); \Sodium\memzero($calc); return $res; } throw new InvalidMessage('Invalid Halite version'); }
/** * Verify a signed message with the correct public key * * @param string $message Message to verify * @param SignaturePublicKey $publicKey * @param string $signature * @param mixed $encoding Which encoding scheme to use? * @return bool * @throws InvalidSignature */ public static function verify(string $message, SignaturePublicKey $publicKey, string $signature, $encoding = Halite::ENCODE_BASE64URLSAFE) : bool { $decoder = Halite::chooseEncoder($encoding, true); if ($decoder) { // We were given hex data: $signature = $decoder($signature); } if (CryptoUtil::safeStrlen($signature) !== \Sodium\CRYPTO_SIGN_BYTES) { throw new InvalidSignature('Signature is not the correct length; is it encoded?'); } return \Sodium\crypto_sign_verify_detached($signature, $message, $publicKey->getRawKeyMaterial()); }