SwiftySRP
这是 SRP 6a 的一个实现,与 BouncyCastle 实现兼容。
有关 SRP 6a 规范,请参阅
如何安装
Cocoapods
要使用 Cocoapods,请将以下行添加到您的 Podfile 中:
pod 'SwiftySRP', '~> 3.1'
Carthage
要使用 Carthage,请将以下行添加到您的 Cartfile 中:
github "flockoffiles/SwiftySRP" ~> 3.1
工作区目标
SwiftySRP
这是一个需要cocoapods支持的目标。
SwiftySRP-iOS
适用于Carthage的目标
SwiftSRP-iOS.static
适用于Carthage的目标。使用静态而不是动态。
如何使用
当前实现仅支持Swift,并支持iOS9.3及以上版本。
要使用客户端的SRP,您需要创建一个SRP协议实例,
其中指定一个大安全素数(下文将说明如何生成一个),一个生成器,一个哈希函数和一个HMAC函数
(HMAC函数用作生成会话密钥的一种替代方法;这样我们就可以通过利用不同的HMAC密钥从相同的共享密钥生成多个会话密钥)。
// In this example we use the same prime that BouncyCastle tests use.
let N = data(hex: "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
+ "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
+ "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
+ "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
+ "FD5138FE8376435B9FC61D2FC0EB06E3")
// In this example we use the same prime that BouncyCastle tests use.
let g = data(hex: "02")
// Use SHA256 as the hashing function, and HMAC-SHA256 as the HMAC function.
let srp256 = try SRP.iMath.protocol(N: N, g:g, digest: CryptoAlgorithm.SHA256.digestFunc(), hmac: CryptoAlgorithm.SHA256.hmacFunc())
之后,您应该生成验证器并将其发送到服务器。(您需要生成一个SRP盐并获取用户名和密码以生成验证器。)
// Normally you would get this from the user:
let userName = "alice".data(using: .utf8)!
// Normally you would get this from the user:
let userPassword = "password123".data(using: .utf8)!
// Just a way to generate the salt... (implemented in a separate category)
let salt = Data.generateRandomBytes(count: 128)
// Generate the verifier
let srpData: SRPData = try srp256.verifier(s: salt, I: userName, p: password)
let verifier: Data = srpData.verifier()
// Now you must send the salt, userName, and the verifier to the server.
在登录时,您必须首先从服务器接收盐和公值'B'参数。然后您可以从用户那里获得用户名和密码,并生成客户端证据消息
let srp = try SRP.iMath.protocol(N: N, g:g, digest: CryptoAlgorithm.SHA256.digestFunc(), hmac: CryptoAlgorithm.SHA256.hmacFunc())
// TODO: Obtain the salt and parameter 'B' from the server.
// Also, the server can send a number of HMAC keys to generate shared session keys.
// let salt: Data = ...
// let B:Data = ...
// let hmacKey1: Data = ...
// TODO: Obtain the userName and password from the user.
// let userName: Data = ...
// let password: Data = ...
var srpData = try srp.generateClientCredentials(s:salt, I:userName, p:password)
srpData.serverPublicValue = B
srpData = try srp.clientEvidenceMessage(srpData: srpData)
// Now send the following values to the server:
// - userName
// - srpData.clientM.serialize()
// - srpData.A.serialize()
// The server will verify the client evidence and, if successful, should send back its own evidence message: serverM
srpData.serverEvidenceMessage = serverM
// Validate the server evidence message:
try srp.verifyServerEvidenceMessage(srpData: clientSRPData)
// Now derive the shared session key.
let clientSharedSessionKey: Data = try! srp.calculateClientSharedKey(srpData: clientSRPData, salt: hmacKey1)
生成安全素数
要生成一个大安全素数,您可以使用,例如,以下方式的openssl:
openssl dhparam -text 2048
这个过程可能相当耗时,但最终你会得到以十六进制形式打印的素数。
示例输出。你可以去掉 ':' 分隔符,并使用结果字符串
...
Diffie-Hellman-Parameters: (2048 bit)
prime:
00:9c:6e:73:6c:3a:9d:9c:22:5c:ce:c9:ab:08:b0:
fa:46:1d:d3:3b:af:39:d7:34:77:54:5a:c9:7a:99:
76:62:bc:f4:b4:a3:1a:51:fe:c9:de:69:d1:c6:7c:
78:a7:18:ad:cb:ae:d9:02:72:1b:a0:2d:45:77:72:
4c:96:d2:ac:74:85:f4:3e:16:96:2d:bb:88:7d:6e:
5f:64:bb:87:69:d2:97:0a:c5:3a:b5:b0:35:34:83:
74:a8:dd:d0:e6:52:d2:e0:41:7d:e9:a7:6d:92:bc:
8d:87:4c:2b:eb:68:e3:53:1d:97:e3:c2:50:82:9d:
3a:db:ca:b6:9f:d5:d4:b5:42:6c:4d:46:c0:94:3b:
45:1d:41:0d:c1:56:d2:56:14:04:84:b2:00:84:07:
d5:4f:b5:11:2b:59:3c:58:c8:18:5e:c1:94:c8:2e:
e9:82:6a:e5:11:3d:0c:96:50:56:04:ea:d3:39:e1:
ea:e4:fc:fd:0d:c3:f7:e9:68:7f:ae:5a:e6:1c:6d:
5a:b8:18:6f:06:68:2d:74:52:80:ae:31:04:75:a8:
00:75:57:c6:bb:de:f7:aa:2c:76:91:36:ff:eb:5e:
86:5e:de:95:7e:f7:86:ab:96:1a:16:56:41:5a:c6:
63:73:3e:e1:9f:c0:85:59:4c:88:55:91:fc:4e:1e:
62:5b
generator: 2 (0x2)
...