# 加密
`crypto/` 汇集了哈希、带密钥的 HMAC、安全随机数、十六进制与 base64
编码,以及 ChaCha20-Poly1305 认证加密。它是一个带命名空间的标准库
家族,被编译进每个运行时,并以带前缀的语法调用
(`[crypto/sha256 $data]`)。在这里字符串兼作字节容器:哈希与
编码函数消费字符串的字节,解码器返回被转回字符串的原始字节 —— 二进制
长度和切片请使用 字符串 中的 `bytes/*` 动词。
## 函数
### 哈希
| 函数 | 用途 |
|---|---|
| `crypto/sha256 $data` | SHA-256 摘要,返回 64 字符的小写十六进制字符串 |
| `crypto/sha512 $data` | SHA-512 摘要,返回 128 字符的小写十六进制字符串 |
| `crypto/blake3 $data` | BLAKE3 摘要,返回 64 字符的小写十六进制字符串 |
| `crypto/md5 $data` | MD5 摘要,返回 32 字符的小写十六进制字符串;密码学上已被攻破,仅用于非安全校验和 |
| `crypto/hash $data :algo` | 按算法分派:`:sha256`、`:sha512`、`:blake3` 或 `:md5`;未知名称时返回 `%Err` |
| `crypto/hmac :algo $key $data` | 带密钥的 HMAC(`:sha256` 或 `:sha512`),返回小写十六进制字符串 |
### 随机数
| 函数 | 用途 |
|---|---|
| `crypto/rand $n` | 从操作系统 CSPRNG 获取 `$n`(1–4096)字节,返回数字向量 |
| `crypto/rand-hex $n` | 同样的随机字节,表示为 `2 * n` 字符的小写十六进制字符串 |
### 编码
| 函数 | 用途 |
|---|---|
| `crypto/b64-encode $data` | 将字符串编码为标准 base64(带填充) |
| `crypto/b64-decode $s` | 将 base64 解码为原始字节(以字符串形式);输入无效时返回 `%Err` |
| `crypto/hex-encode $data` | 将字节编码为小写十六进制(`2 * len` 字符) |
| `crypto/hex-decode $hex` | 将十六进制解码为原始字节(以字符串形式);长度必须为偶数,至多 8192 字符 |
### 认证加密
| 函数 | 用途 |
|---|---|
| `crypto/encrypt :chacha20-poly1305 $key-hex $nonce-hex $plaintext ?$aad` | AEAD 加密;返回 `%Encrypted{ :ciphertext hex :tag hex }` |
| `crypto/decrypt :chacha20-poly1305 $key-hex $nonce-hex $ciphertext-hex $tag-hex ?$aad` | AEAD 解密;返回明文字符串,认证失败时返回 `%Err` |
说明:
- 所有摘要和编码值都是小写十六进制或标准带填充 base64;解码器接受
这些形式并返回原始字节字符串,因此解码后的数据块可以直接传回
`crypto/encrypt`,或用 `fs/write` 写入。
- `crypto/hmac` 的算法参数在最前:`[crypto/hmac :sha256 $key $data]`。
- 对于 AEAD 调用,密钥是 32 字节,表示为 64 个十六进制
字符(用 `[crypto/rand-hex 32]` 生成);nonce 是 12 字节,
表示为 24 个十六进制字符;tag 是 16 字节,表示为 32 个十六进制字符。
可选的 AAD 会被 tag 覆盖但不加密,解密时必须一致。
- MD5 仅为兼容性和校验和保留 —— 不要将其用于签名、完整性校验或密码存储。
## 示例
### 哈希与 HMAC
set payload "hello" echo [crypto/sha256 $payload] echo [crypto/sha512 $payload] echo [crypto/blake3 $payload] echo [crypto/md5 $payload] echo [crypto/hash $payload :sha256] # same as crypto/sha256 echo [crypto/hmac :sha256 "secret-key" $payload]
### 十六进制与 base64 编码
set b64 [crypto/b64-encode "hello"] # aGVsbG8= echo [crypto/b64-decode $b64] # hello echo [crypto/hex-encode "hello"] # 68656c6c6f echo [crypto/hex-decode "68656c6c6f"] # hello
### 随机令牌
def session [crypto/rand-hex 32] # 64-character hex session id def noise [crypto/rand 16] # @{ 0-255 ... } byte vector echo $session(len) $noise(len)
### 认证加密
def key [crypto/rand-hex 32] # 32-byte key as 64 hex chars def nonce [crypto/rand-hex 12] # 12-byte nonce as 24 hex chars def sealed [crypto/encrypt :chacha20-poly1305 $key $nonce "secret message"] set plain [crypto/decrypt :chacha20-poly1305 $key $nonce $sealed~ciphertext $sealed~tag] echo $plain # secret message