一个用于解码、验证和校验欧盟数字 COVID 证书的 Swift 包
适用于 iOS、tvOS、watchOS 和 macOS
EUDCCKit 并非欧盟数字 COVID 证书的官方实现
要使用 Apple 的 Swift 包管理器进行集成,请将以下内容作为依赖项添加到您的 Package.swift
中
dependencies: [
.package(url: "https://github.com/SvenTiigi/EUDCCKit.git", from: "0.0.1")
]
或者导航到您的 Xcode 项目,然后选择 Swift Packages
,单击“+”图标并搜索 EUDCCKit
。
EUDCCKit
Swift 包由四个不同的库组成,用于解码、验证和校验欧盟数字 COVID 证书。
EUDCC
库包含欧盟数字 COVID 证书的模型定义
import EUDCC
// The EU Digital COVID Certificate model
let eudcc: EUDCC
// Access content of EUDCC
switch eudcc.content {
case .vaccination(let vaccination):
print("Vaccination", vaccination)
case .test(let test):
print("Test", test)
case .recovery(let recovery):
print("Recovery", recovery)
}
请访问高级部分以了解更多信息。
EUDCCDecoder
库提供了一个 EUDCCDecoder
对象,该对象能够解码欧盟数字 COVID 证书的 Base-45 字符串表示形式,该形式通常嵌入在二维码中。
import EUDCCDecoder
// Initialize an EUDCCDecoder
let decoder = EUDCCDecoder()
// The Base-45 encoded EU Digital COVID Certificate from a QR-Code
let qrCodeContent = "HC1:..."
// Decode EUDCC from QR-Code
let decodingResult = decoder.decode(from: qrCodeContent)
// Switch on decoding result
switch decodingResult {
case .success(let eudcc):
// Successfully decoded Digital COVID Certificate
print("EU Digital COVID Certificate", eudcc)
case .failure(let decodingError):
// Decoding failed with error
print("Failed to decode EUDCC", decodingError)
}
请访问高级部分以了解更多信息。
EUDCCVerifier
库提供了一个 EUDCCVerifier
对象,该对象可用于验证欧盟数字 COVID 证书的加密签名。
import EUDCCVerifier
// Initialize an EUDDCCVerifier
let verifier = EUDCCVerifier(
trustService: EUCentralEUDCCTrustService()
)
// Verify EU Digital COVID Certificate
verifier.verify(eudcc: eudcc) { verificationResult in
// Switch on verification result
switch verificationResult {
case .success(let trustCertificate):
print("Cryptographically valid", trustCertificate)
case .invald:
print("Invalid EUDCC")
case .failure(let error):
print("Error occured during verification", error)
}
}
请访问高级部分以了解更多信息。
EUDCCValidator
库提供了一个 EUDCCValidator
对象,该对象可用于根据给定的规则校验欧盟数字 COVID 证书。
import EUDCCValidator
// Initialize an EUDCCValidator
let validator = EUDCCValidator()
// Validate EU Digital COVID Certificate
let validationResult = validator.validate(
eudcc: eudcc,
rule: .isFullyImmunized() && !.isVaccinationExpired()
)
// Switch on validation result
switch validationResult {
case .success:
// Successfully validated EU Digital COVID Certificate
print("Successfully validated")
case .failure(let validationError):
// Validation failure
print("Validation failed", validationError)
}
请访问高级部分以了解更多信息。
除了 EUDCC
的 content
属性之外,您还可以使用以下便捷属性来检查 EUDCC
是否包含疫苗接种、检测或康复对象。
import EUDCC
// Vaccination
let vaccination: EUDCC.Vaccination? = eudcc.vaccination
// Test
let test: EUDCC.Test? = eudcc.test
// Recovery
let recovery: EUDCC.Recovery? = eudcc.recovery
以下每个对象都公开了一个 WellKnownValue
枚举,该枚举可用于检索有关特定值的更详细信息
EUDCC.DiseaseAgentTargeted
EUDCC.Test.TestResult
EUDCC.Test.TestType
EUDCC.Vaccination.VaccineMarketingAuthorizationHolder
EUDCC.Vaccination.VaccineMedicinalProduct
EUDCC.Vaccination.VaccineOrProphylaxis
import EUDCC
let vaccineMedicinalProduct: EUDCC.Vaccination.VaccineMedicinalProduct
// Switch on WellKnownValue of VaccineMedicinalProduct
switch vaccineMedicinalProduct.wellKnownValue {
case .covid19VaccineModerna:
break
case .vaxzevria:
break
default:
break
}
EUDCC
包含两个属性 cryptographicSignature
和 base45Representation
,它们是方便的对象,并非欧盟数字 COVID 证书 JSON 架构的正式组成部分。
如果您希望在编码 EUDCC
时跳过这些属性,您可以将以下 userInfo
配置设置为 JSONEncoder
。
import EUDCC
let encoder = JSONEncoder()
encoder.userInfo = [
// Skip encoding CryptographicSignature
EUDCC.EncoderUserInfoKeys.skipCryptographicSignature: true,
// Skip encoding Base-45 representation
EUDCC.EncoderUserInfoKeys.skipBase45Representation: true,
]
let jsonData = try encoder.encode(eudcc)
EUDCCDecoder
支持解码 Base-45 编码的 String
和 Data
对象。
import EUDCCDecoder
let eudccDecoder = EUDCCDecoder()
// Decode from Base-45 encoded String
let eudccBase45EncodedString: String
let stringDecodingResult = eudccDecoder.decode(
from: eudccBase45EncodedString
)
// Decode from Base-45 encoded Data
let eudccBase45EncodedData: Data
let dataDecodingResult = eudccDecoder.decode(
from: eudccBase45EncodedData
)
通过导入 EUDCCDecoder
库,EUDCC
对象将扩展一个静态 decode
函数。
import EUDCCDecoder
let decodingResult = EUDCC.decode(from: "HC1:...")
为了验证 EUDCC
,需要使用 EUDCCTrustService
的实例来实例化 EUDCCVerifier
,该实例用于检索信任证书。
import EUDCC
import EUDCCVerifier
struct SpecificEUDCCTrustService: EUDCCTrustService {
/// Retrieve EUDCC TrustCertificates
/// - Parameter completion: The completion closure
func getTrustCertificates(
completion: @escaping (Result<[EUDCC.TrustCertificate], Error>) -> Void
) {
// TODO: Retrieve TrustCertificates and invoke completion handler
}
}
let eudccVerifier = EUDCCVerifier(
trustService: SpecificEUDCCTrustService()
)
EUDCCKit
附带了两个预定义的 EUDCCTrustService
实现
EUCentralEUDCCTrustService
RobertKochInstituteEUDCCTrustService
如果您希望从多个 EUDCCTrustService
实现中检索证书,则可以使用 GroupableEUDCCTrustService
let trustService = GroupableEUDCCTrustService(
trustServices: [
EUCentralEUDCCTrustService(),
RobertKochInstituteEUDCCTrustService()
]
)
trustService.getTrustCertificates { certificates in
// ...
}
通过导入 EUDCCVerifier
库,EUDCC
对象将扩展一个 verify
函数。
import EUDCC
import EUDCCVerifier
let eudcc: EUDCC
eudcc.verify(
using: EUDCCVerifier(
trustService: EUCentralEUDCCTrustService()
)
) { verificationResult in
switch verificationResult {
case .success(let trustCertificate):
break
case .invald:
break
case .failure(let error):
break
}
}
可以使用 EUDCCValidator
和给定的 EUDCC.ValidationRule
来校验 EUDCC
。 EUDCC.ValidationRule
可以用一个简单的闭包初始化,该闭包接收一个 EUDCC
并返回一个 Bool
,指示校验是成功还是失败。
import EUDCC
import EUDCCValidator
// Simple EUDCC ValidationRule instantiation
let validationRule = EUDCC.ValidationRule { eudcc in
// Process EUDCC and return Bool result
}
// EUDCC ValidationRule with Tag in order to uniquely identify a ValidationRule
let isVaccinationComplete = EUDCC.ValidationRule(
tag: "is-vaccination-complete"
) { eudcc in
eudcc.vaccination?.doseNumber == eudcc.vaccination?.totalSeriesOfDoses
}
EUDCCKit
附带了许多预定义的 EUDCC.ValidationRule
,例如以下这些。
import EUDCC
import EUDCCValidator
let eudcc: EUDCC
let validator = EUDCCValidator()
// Is fully immunized
validator.validate(
eudcc: eudcc,
rule: .isFullyImmunized(minimumDaysPast: 15)
)
// Is tested positive
validator.validate(
eudcc: eudcc,
rule: .isTestedPositive
)
为了创建更复杂的规则,每个 EUDCC.ValidationRule
都可以通过应用标准运算符链接在一起。
import EUDCC
import EUDCCValidator
let defaultValidationRule: EUDCC.ValidationRule = .if(
.isVaccination,
then: .isFullyImmunized() && .isWellKnownVaccineMedicinalProduct && !.isVaccinationExpired(),
else: .if(
.isTest,
then: .isTestedNegative && .isTestValid(),
else: .if(
.isRecovery,
then: .isRecoveryValid,
else: .constant(false)
)
)
)
通过导入 EUDCCValidator
库,EUDCC
对象将扩展一个 validate
函数。
import EUDCC
import EUDCCValidator
let eudcc: EUDCC
let validationRule = eudcc.validate(
rule: .isWellKnownVaccineMedicinalProduct
)
EUDCCKit
Copyright (c) 2021 Sven Tiigi sven.tiigi@gmail.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.