Trifle
Trifle SDK 是为了在客户端应用程序和后端服务之间(即使跨越 TLS 终止点)促进应用级安全通信而设计的。SDK 建立了一个标准化框架,确保
- 后端服务能够验证客户端数据的真实性和完整性
- 向后端服务提供客户端应用程序的信号
这些安全保证是在传输层安全性(如 TLS)之上应用的,允许在更细致的粒度上应用数据安全策略。
Trifle SDK 与提供的证书颁发机构集成,为客户端应用程序提供格式化的 Trifle 证书。该证书当前仅捕捉客户端应用程序的身份。
Trifle SDK 有两个主要组件
- 标准化的便利 API,提供在给定的本地平台上推荐的建立安全措施,封装了实现复杂性。
- 标准化安全实体的消息格式,包括证书、密文和签名。
Trifle SDK 在 iOS 和 Android 的客户端实现,并在 Kotlin 的服务器端实现。
Swift SDK 使用
// App start up
let trifle = try Trifle(reverseDomain: abc)
// Check if a key already exists.
// If no key exists, generate a public key pair
let keyHandle = try trifle.generateKeyHandle()
// Storing keys. Keys are codable.
let encoder = JSONEncoder()
let jsonKeyHandle = try encoder.encode(keyHandle)
// Load the key from storage when we need to use it
let decoder = JSONDecoder()
let decoded = try decoder.decode(TrifleKeyHandle.self, from: jsonKeyHandle)
// Check the validity of loaded key
let valid = trifle.isValid(keyHandle: keyHandle)
// Destroy key that is no longer in use or is invalid
let status = trifle.delete(keyHandle: keyHandle)
// Destroy key that is no longer in use or is invalid
let status = trifle.delete(keyHandle: keyHandle)
// Check if loaded key already has a cert. If yes, skip to checking for cert validity
// Else if key does not have a cert OR if a new cert must be generated (eg because of existing
// cert is already expired, or app needs to re-attest, app is re-installed, app is restored
// from backup, ... etc)
// Create cert request
let certReq = try trifle.generateMobileCertificateRequest(entity: entity, keyHandle: keyHandle)
// Serialize to proto to be sent over wire
let encoded = try certReq.serialize()
// Send certificate request to Certificate Authority endpoint. Response will be [Data]
let response: [Data]
// Iterate over each Data to convert to TrifleCertificate
let certs = try response.map({ try TrifleCertificate.deserialize(data: $0) })
// certs is an array of certificates where [0] will be device certificate
// and the rest of the elements will be intermediate chain.
// For the following, verify API can throw a number of errors as defined by TrifleError
// Check if app has the root cert of Certificate Authority (CA).
// Validate cert matches the certificate request (so generated key)
// and the root (so it has been generated by the right CA).
let isValid = certs[0].verify(
certificateRequest: certRequest,
intermediateTrifleChain: certs,
rootTrifleCertificate: root)
// Once it passes validation, certReq is no longer needed and it can be deleted
// Store cert along with the respective keyHandle
// To check only for the validity of a stored cert, you can do either of below choices
// Option 1 is a more complete check of the device cert and the full chain
isValid = certs[0].verify(intermediateChain: certs )
// option 2 only checks the validity of the device cert
isValid = certs[0].verify(intermediateChain: [] )
// Sign the data
let trifleSignedData = try trifle.createSignedData(
data: dataThatIsSigned,
keyHandle: keyHandle,
certificates: certs )
// Serialize to proto to be sent over wire
let encodedTrifleSignedDataProto = try trifleSignedData.serialize()
Android SDK 使用
// Check if a key already exists.
// If no key exists, generate a public key pair
var keyHandle: KeyHandle = TrifleApi.generateKeyHandle("abc")
// Storing keys. Key handles are serializable.
val encoded: ByteArray = keyHandle.serialize()
// Load the key from storage when we need to use it
val decoded: KeyHandle = KeyHandle.deserialize(encoded)
// Check the validity of loaded key
val valid: Boolean = trifleApi.isValid(keyHandle)
// Destroy key that is no longer in use or is invalid
trifleApi.delete(keyHandle)
// Check if loaded key already has a cert. If yes, skip to checking for cert validity
// Else if key does not have a cert OR if a new cert must be generated (eg because of existing
// cert is already expired, or app needs to re-attest, app is re-installed, app is restored
// from backup, ... etc)
// Create cert request with an entity identity that is associated with the public key
val certReq: CertificateRequest = TrifleApi.generateMobileCertificateRequest(entity, keyHandle)
// Serialize as an opaque ByteArray
val encoded: ByteArray = certReq.serialize()
// Send certificate request to Certificate Authority endpoint. Response will be List<ByteArray>
val response: List<ByteArray>
// Iterate over each ByteArray to convert to Certificate
val certs: List<Certificate> = response.map { Certificate.deserialize(it) }
// certs is a list of certificates where [0] will be device certificate
// and the rest of the elements will be intermediate chain.
// Check if app has the root cert of Certificate Authority (CA).
// Validate cert matches the certificate request (so generated key)
// and the root (so it has been generated by the right CA).
val result: Result<Unit> = TrifleApi.verify(certs[0], certReq, certs, root)
// Once it passes validation, certReq is no longer needed, and it can be deleted
// Store cert along with the respective keyHandle
// To check only for the validity of a stored cert, you can do either of below choices
// Option 1 is a more complete check of the device cert and the full chain
val result: Result<Unit> = TrifleApi.verify(cert, ancestorCertificateChain = certs.drop(1))
// option 2 only checks the validity of the device cert
val result: Result<Unit> = TrifleApi.verify(cert)
// Error handling from the Result.isFailure can be found in the enumeration in TrifleErrors
if (result.isFailure) {
when (result.getExceptionOrNull) {
is NoTrustAnchor -> {} // trust anchor is missing
is InvalidCertPath -> {} // certificate path is invalid
is ExpiredCertificate -> {} // certificate has expired
is InvalidSignature -> {} // signature did not match
is CSRMismatch -> {} // attributes in the cert did not match CSR
else -> {} // unspecified failure
}
}
// Sign the data
val signedData: SignedData = TrifleApi.createSignedData(clientData, keyHandle, certs)
// Serialize as an opaque ByteArray
val encodedSignedData: ByteArray = signedData.serialize()
密钥生命周期
待定
证书生命周期
待定
路线图
Trifle 路线图包括以下一些特性
- 后端服务能够与客户端应用交换私密消息
- 在证书中包含客户端提供的属性和/或用户信息
- 扩展客户端 SDK 到 Web