From dc4ee475999563a4a0e6f102644208a6954aaaf7 Mon Sep 17 00:00:00 2001 From: JIN Date: Fri, 12 Aug 2022 20:26:52 +0800 Subject: [PATCH] Add security cryto & passwords translation (#698) --- docs/security/crypto.zh.md | 98 +++++++++++++++++++++++++++++++++++ docs/security/passwords.zh.md | 89 +++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 docs/security/crypto.zh.md create mode 100644 docs/security/passwords.zh.md diff --git a/docs/security/crypto.zh.md b/docs/security/crypto.zh.md new file mode 100644 index 00000000..f5a16ccc --- /dev/null +++ b/docs/security/crypto.zh.md @@ -0,0 +1,98 @@ +# 加密 + +Vapor 中包含 [SwiftCrypto](https://github.com/apple/swift-crypto/) 库,这是苹果 CryptoKit 库的 Linux 兼容端口。SwiftCrypto 还没有公开一些额外的加密 API,比如 [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt) 和 [TOTP](https://en.wikipedia.org/wiki/Time-based_One-time_Password_algorithm)。 + +## SwiftCrypto + +Swift 的 `Crypto` 库实现了苹果的 CryptoKit API。因此,[CryptoKit 文档](https://developer.apple.com/documentation/cryptokit)和 [WWDC 演讲](https://developer.apple.com/videos/play/wwdc2019/709)是学习 API 的绝佳资源。 + +导入 Vapor,即可使用这些 API。 + +```swift +import Vapor + +let digest = SHA256.hash(data: Data("hello".utf8)) +print(digest) +``` + +CryptoKit 支持下列哈希算法: + +- 哈希:`SHA512`, `SHA384`, `SHA256` +- 消息验证码:`HMAC` +- 密码:`AES`, `ChaChaPoly` +- 公钥密码:`Curve25519`, `P521`, `P384`, `P256` +- 不安全的哈希: `SHA1`, `MD5` + +## Bcrypt + +Bcrypt 是一种密码哈希算法,它使用一个随机的盐来确保对相同的密码进行多次哈希不会得到相同的摘要。 + +Vapor 提供了一个 `Bcrypt` 类型用于哈希和密码比较。 + +```swift +import Vapor + +let digest = try Bcrypt.hash("test") +``` + +因为 Bcrypt 使用了盐,所以不能直接比较密码哈希值。明文密码和现有摘要必须同时进行验证。 + +```swift +import Vapor + +let pass = try Bcrypt.verify("test", created: digest) +if pass { + // 密码和摘要匹配。 +} else { + // 错误密码。 +} +``` + +使用 Bcrypt 密码登录可以根据电子邮件或用户名从数据库中获取用户的密码摘要来实现。然后根据提供的明文密码验证已知的摘要。 + +## OTP + +Vapor 支持 HOTP 和 TOTP 一次性密码。OTP 使用 SHA-1、SHA-256 和 SHA-512 哈希函数,可以提供六、七或八位数的输出。OTP 通过生成一次性人类可读密码来提供身份验证。为此,各方首先就对称密钥达成一致,该密钥必须始终保密,以维护生成密码的安全性。 + +#### HOTP + +HOTP 是一种基于 HMAC 签名的 OTP。除了对称密钥之外,双方还约定了一个计数器,这是一个为密码提供唯一性的数字。每次尝试后,计数器都会增加。 + +```swift +let key = SymmetricKey(size: .bits128) +let hotp = HOTP(key: key, digest: .sha256, digits: .six) +let code = hotp.generate(counter: 25) + +// 或者使用静态生成函数 +HOTP.generate(key: key, digest: .sha256, digits: .six, counter: 25) +``` + +#### TOTP + +TOTP 是 HOTP 的基于时间的变体。它的工作原理基本相同,但不是简单的计数器,而是使用当前时间来生成唯一性。为了补偿由不同步的时钟、网络延迟、用户延迟和其他混杂因素引入的不可避免的偏差,生成的 TOTP 代码在指定的时间间隔(最常见的是30秒)内保持有效。 + +```swift +let key = SymmetricKey(size: .bits128) +let totp = TOTP(key: key, digest: .sha256, digits: .six, interval: 60) +let code = totp.generate(time: Date()) + +// 或者使用静态生成函数 +TOTP.generate(key: key, digest: .sha256, digits: .six, interval: 60, time: Date()) +``` + +#### Range + +OTP 在提供验证和非同步计数器方面非常有用。两种 OTP 实现都能够生成一个具有容错性的 OTP。 + +```swift +let key = SymmetricKey(size: .bits128) +let hotp = HOTP(key: key, digest: .sha256, digits: .six) + +// 生成一个正确计数器窗口 +let codes = hotp.generate(counter: 25, range: 2) +``` + +上面的示例允许边距为2,这意味着 HOTP 将计算计数器值为`23...27`,所有这些代码都会被返回。 + +!!! 警告 + 注意:使用的误差范围越大,攻击者采取行动的时间和自由度就越多,从而降低了算法的安全性。 diff --git a/docs/security/passwords.zh.md b/docs/security/passwords.zh.md new file mode 100644 index 00000000..dddb1dae --- /dev/null +++ b/docs/security/passwords.zh.md @@ -0,0 +1,89 @@ +# 密码 + +Vapor 包含一个密码哈希 API,可帮助你安全地存储和验证密码。此 API 可根据环境进行配置,并支持异步哈希。 + +## 配置 + +使用 `app.passwords` 配置应用的密码哈希器 + +```swift +import Vapor + +app.passwords.use(...) +``` + +### Bcrypt + +要使用 Vapor 的 [Bcrypt API](crypto.zh.md#bcrypt) 进行密码哈希,请指定 `.bcrypt`。这也是默认设置。 + +```swift +app.passwords.use(.bcrypt) +``` + +除非另有说明,否则 Bcrypt 将使用 cost 为12的默认值。你可以通过传递 `cost` 参数来配置它。 + +```swift +app.passwords.use(.bcrypt(cost: 8)) +``` + +### 纯文本 + +Vapor 包含一个不安全的密码哈希器,它以明文形式存储和验证密码。这不应该在生产环境中使用,但对测试很有用。 + +```swift +switch app.environment { +case .testing: + app.passwords.use(.plaintext) +default: break +} +``` + +## Hashing + +使用 `Request` 对象上的 `password` 辅助函数对密码进行哈希。 + +```swift +let digest = try req.password.hash("vapor") +``` + +可以使用 `verify` 方法针对明文密码验证密码摘要。 + +```swift +let bool = try req.password.verify("vapor", created: digest) +``` + +同样的 API 也可以在 `Application` 中使用。 + +```swift +let digest = try app.password.hash("vapor") +``` + +### 异步 + +密码哈希算法被设计成速度慢且耗费 CPU 资源。在对密码进行哈希时,你可能希望避免阻塞事件循环。Vapor 提供了一个异步密码哈希 API,它将哈希分派给后台线程池。要使用异步 API,请使用密码哈希器上的 `async` 属性。 + +```swift +req.password.async.hash("vapor").map { digest in + // Handle digest. +} + +// or + +let digest = try await req.password.async.hash("vapor") +``` + +验证摘要的工作原理类似: + +```swift +req.password.async.verify("vapor", created: digest).map { bool in + // Handle result. +} + +// or + +let result = try await req.password.async.verify("vapor", created: digest) +``` + +在后台线程上计算哈希值可以释放应用程序的事件循环来处理更多的传入请求。 + +