# `naisi_hash_password`

使用业务盐和当前构建的内部密码材料生成确定性的密码存储字符串。

本函数不会读取许可文件中的项目私有盐、客户 ID、Build ID 或设备指纹。
相同密码字节、盐、内部密码材料及算法版本会得到相同结果，适合在数据库中存储后
重新计算并比较；不同服务器必须部署相同的内部密码材料。

注意：结果不可逆，不是可解密密文。升级时若重新生成内部密码材料，旧密码结果将
无法重算，已有用户也无法继续用原密码完成比较；应安全保留并迁移对应版本的私有
构建材料。不得记录密码、盐或中间材料，也不要用本函数生成访问令牌。

## 函数签名

```php
function naisi_hash_password(string $password, string $salt): ?string
```

## 调用前提

应用入口先调用 [naisi_is_ext_license_valid](/web/developers/naisilib/naisi-is-ext-license-valid) 并确认返回 `true`。认证 Agent 发布的许可与 heartbeat 快照，并建立或复用本请求的 BASIC 证明；不会读取许可文件或检查当前 Host。

授权类别：`LICENSE`；执行模式：`BASIC`。许可不代替登录、租户或权限上下文；身份与数据要求见本页参数及用途说明。

## 参数

### `$password`

- 类型：`string`
- 必填：是
- 默认值：无
- 方向：输入参数。

需要生成存储值的原始密码字节字符串。空密码为兼容输入并会正常生成存储值；本函数不检查密码强度，业务层必须先拒绝空密码和弱密码。

### `$salt`

- 类型：`string`
- 必填：是
- 默认值：无
- 方向：输入参数。

调用方提供并负责稳定保存的业务盐字节字符串；空盐为兼容输入但不建议生产使用。验证同一密码时必须逐字节一致；盐不会自动从许可文件取得。

## 返回值

类型：`string|null`

成功时返回固定 86 字符的项目格式密码存储字符串；未授权、材料不可用或计算失败时返回 null。验证时应先严格判断返回值不是 null，再使用安全的字符串比较方式。

## 调用示例

当前请求须满足上方调用前提；请检查实际返回值和引用输出，随机结果及数据包内容以运行环境为准。

```php
$password = 'StrongPass!2026';
$salt = 'test_salt_2026';

$result = naisi_hash_password($password, $salt);
var_dump($result);
```

## 版本信息

- 自版本：`1.0.6`
- 实现模块：`crypto`
- 授权类别：`LICENSE` / `BASIC`
- 失败回退：`null`
- 文档同步：`2026-10-18`
