JSONWebToken
Swift 库,用于解码、验证、签名和验证 JWT
功能
- 验证和签名
- HMAC
HS256
HS384
HS512
- RSASSA-PKCS1-v1_5
RS256
RS384
RS384
- HMAC
- (可选)验证所有已注册的声明
- 发行者
iss
- 主题
sub
- 受众
aud
- 过期时间
exp
- 生效时间
nbf
- 发放时间
iat
- JWT ID
jti
- 发行者
- 无外部依赖:使用 CommonCrypto 和 Security 框架进行签名和验证
- 可扩展性:可添加您自己的声明验证器和签名操作
用法
解码 & 验证
import JSONWebToken
let rawJWT : String
let jwt : JSONWebToken = try JSONWebToken(string : rawJWT)
//create the validator by combining other validators with the & or | operator
let validator = RegisteredClaimValidator.expiration &
RegisteredClaimValidator.notBefore.optional &
HMACSignature(secret: "secret".dataUsingEncoding(NSUTF8StringEncoding)!, hashFunction: .SHA256)
/*
- not expired
- can be used now (optional : a jwt without nbf will be valid)
- signed with HS256 and the key "secret"
*/
let validationResult = validator.validateToken(jwt)
guard case ValidationResult.Success = validationResult else { return }
//use the token and access the payload
let issuer : String? = jwt.payload.issuer
let customClaim = jwt.payload["customClaim"] as? String
签署
import JSONWebToken
//build the payload
var payload = JSONWebToken.Payload()
payload.issuer = "http://kreactive.com"
payload.subject = "antoine"
payload.audience = ["com.kreactive.app"]
payload.expiration = NSDate().dateByAddingTimeInterval(300)
payload.notBefore = NSDate()
payload.issuedAt = NSDate()
payload.jwtIdentifier = NSUUID().UUIDString
payload["customClaim"] = "customClaim"
//use HS256 to sign the token
let signer = HMACSignature(secret: "secret".dataUsingEncoding(NSUTF8StringEncoding)!, hashFunction: .SHA256)
//build the token, signer is optional
let jwt = try JSONWebToken(payload : payload, signer : signer)
let rawJWT : String = jwt.rawString
RSASSA-PKCS1-v1_5 签名
密钥
密钥由 RSAKey
结构体表示,封装了一个 SecKeyRef
。导入 公钥 的推荐方法是使用 DER编码的X.509
证书 (.cer),导入 私钥 则使用 PKCS#12
(.p12) 身份。也可以通过使用密钥链项导入副作用来导入密钥的原始表示(X509,公开pem,模数/指数...)。
let certificateData : NSData = //DER-encoded X.509 certificate
let publicKey : RSAKey = try RSAKey(certificateData : certificateData)
let p12Data : NSData //PKCS #12–formatted identity data
let identity : (publicKey : RSAKey, privateKey : RSAKey) = try RSAKey.keysFromPkcs12Identity(p12Data, passphrase : "pass")
let keyData : NSData
//import key into the keychain
let key : RSAKey = try RSAKey.registerOrUpdateKey(keyData, tag : "keyTag")
let modulusData : NSData
let exponentData : NSData
//import key into the keychain
let key : RSAKey = try RSAKey.registerOrUpdateKey(modulus : modulusData, exponent : exponentData, tag : "keyTag")
从密钥链中检索或删除密钥
//get registered key
let key : RSAKey? = RSAKey.registeredKeyWithTag("keyTag")
//remove
RSAKey.removeKeyWithTag("keyTag")
大部分原始密钥导入代码是从 Heimdall 库复制的。
验证
使用 RSAPKCS1Verifier
作为验证器来验证令牌签名
let jwt : JSONWebToken
let publicKey : RSAKey
let validator = RegisteredClaimValidator.expiration &
RegisteredClaimValidator.notBefore.optional &
RSAPKCS1Verifier(key : publicKey, hashFunction: .SHA256)
let validationResult = validator.validateToken(jwt)
...
签署
使用 RSAPKCS1Signer
生成已签名的令牌
let payload : JSONWebToken.Payload
let privateKey : RSAKey
let signer = RSAPKCS1Signer(hashFunction: .SHA256, key: privateKey)
let jwt = try JSONWebToken(payload : payload, signer : signer)
let rawJWT : String = jwt.rawString
...
验证
验证器(签名和声明)实现了协议 JSONWebTokenValidatorType
public protocol JSONWebTokenValidatorType {
func validateToken(token : JSONWebToken) -> ValidationResult
}
在任何 类
或 结构体
上实现此协议允许它通过使用 |
或 &
运算符与其他验证器组合。验证方法返回一个 ValidationResult
public enum ValidationResult {
case Success
case Failure(ErrorType)
public var isValid : Bool
}
声明验证
您可以使用 ClaimValidator
结构体来实现声明验证器
public struct ClaimValidator<T> : JSONWebTokenValidatorType {
}
let validator : ClaimValidator<Int> = ClaimValidator(key: "customClaim", transform: { (jsonValue : AnyObject) throws -> Int in
guard let numberValue = jsonValue as? NSNumber else {
throw ClaimValidatorError(message: "customClaim value \(jsonValue) is not the expected Number type")
}
return numberValue.integerValue
}).withValidator { 1..<4 ~= $0 }
所有已注册的声明验证器都已实现
RegisteredClaimValidator.issuer
:iss
声明已定义,类型为String
RegisteredClaimValidator.subject
:sub
声明已定义,类型为String
RegisteredClaimValidator.audience
:aud
声明已定义,类型为String
或[String]
RegisteredClaimValidator.expiration
:exp
声明已定义,类型为Integer
,可转换为NSDate
,且在当前日期之后RegisteredClaimValidator.notBefore
:nbf
声明已定义,类型为Integer
,可转换为NSDate
,且在当前日期之前RegisteredClaimValidator.issuedAt
:iat
声明已定义,类型为Integer
,可转换为NSDate
RegisteredClaimValidator.jwtIdentifier
:jti
声明已定义,类型为String
它可以被扩展
let myIssuerValidator = RegisteredClaimValidator.issuer.withValidator { $0 == "kreactive" }
不支持的签名
验证
在任何 class
或 struct
上实现 SignatureValidator
协议以添加不支持的签名算法验证器。
public protocol SignatureValidator : JSONWebTokenValidatorType {
func canVerifyWithSignatureAlgorithm(alg : SignatureAlgorithm) -> Bool
func verify(input : NSData, signature : NSData) -> Bool
}
签名
在任何 class
或 struct
上实现 TokenSigner
协议以使用不支持的签名算法进行签名。
public protocol TokenSigner {
var signatureAlgorithm : SignatureAlgorithm {get}
func sign(input : NSData) throws -> NSData
}