# 加密 `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
## 另见 - 字符串 —— 用于二进制安全长度与切片的 `bytes/*` 动词 - 压缩 —— 针对编码数据块的 gzip、tar 与 tarball 辅助函数 - 文件系统 —— 读取和写入二进制文件以进行哈希或封装 - 数据格式 —— 序列化之后会被签名或哈希的值