getMessage(); } $sealed = self::seal( $mnemonic ); if ( '' === $sealed ) { return 'This server has no working encryption (openssl), so the phrase cannot be stored safely.'; } update_option( self::OPT_PHRASE, $sealed, false ); update_option( self::OPT_ADDRESS, $key['address'], false ); return ''; } /** The address the stored phrase publishes from, or ''. */ public static function publishing_address() { return (string) get_option( self::OPT_ADDRESS, '' ); } /** * The private key for signing gateway writes. * * @return string 32 raw bytes, or '' when nothing is stored. * @throws Exception When the stored phrase cannot be unsealed or derived. */ public static function publishing_private_key() { $sealed = (string) get_option( self::OPT_PHRASE, '' ); if ( '' === $sealed ) { return ''; } $mnemonic = self::unseal( $sealed ); if ( '' === $mnemonic ) { throw new Exception( 'The stored recovery phrase could not be decrypted. If SIRIUS_PRESS_KEY or the site salts changed, re-enter the phrase in Sirius Press settings.' ); } $key = SP_HD::publishing_key( $mnemonic, self::prefix(), self::derivation_path() ); return $key['private']; } // ------------------------------------------------------------ encryption /** 32-byte key from the site's configured secret. */ private static function secret() { $material = defined( 'SIRIUS_PRESS_KEY' ) && SIRIUS_PRESS_KEY ? SIRIUS_PRESS_KEY : ( ( defined( 'AUTH_KEY' ) ? AUTH_KEY : '' ) . ( defined( 'SECURE_AUTH_SALT' ) ? SECURE_AUTH_SALT : '' ) ); return hash( 'sha256', 'sirius-press/v1/' . $material, true ); } /** @return string base64 of iv|tag|ciphertext, or '' if unavailable. */ private static function seal( $plain ) { if ( ! function_exists( 'openssl_encrypt' ) ) { return ''; } $iv = random_bytes( 12 ); $tag = ''; $ct = openssl_encrypt( $plain, 'aes-256-gcm', self::secret(), OPENSSL_RAW_DATA, $iv, $tag, 'sirius-press', 16 ); if ( false === $ct ) { return ''; } return base64_encode( $iv . $tag . $ct ); } /** @return string '' when the blob cannot be authenticated. */ private static function unseal( $sealed ) { if ( ! function_exists( 'openssl_decrypt' ) ) { return ''; } $raw = base64_decode( $sealed, true ); if ( false === $raw || strlen( $raw ) < 29 ) { return ''; } $plain = openssl_decrypt( substr( $raw, 28 ), 'aes-256-gcm', self::secret(), OPENSSL_RAW_DATA, substr( $raw, 0, 12 ), substr( $raw, 12, 16 ), 'sirius-press' ); return false === $plain ? '' : $plain; } }