Add security cryto & passwords translation (#698)

This commit is contained in:
JIN 2022-08-12 20:26:52 +08:00 committed by GitHub
parent 25a39695f5
commit dc4ee47599
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 187 additions and 0 deletions

View File

@ -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`,所有这些代码都会被返回。
!!! 警告
注意:使用的误差范围越大,攻击者采取行动的时间和自由度就越多,从而降低了算法的安全性。

View File

@ -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)
```
在后台线程上计算哈希值可以释放应用程序的事件循环来处理更多的传入请求。