Trifle 0.2.5

Trifle 0.2.5

Alvin SeeGelareh Taban 维护。



Trifle 0.2.5

  • Cash App

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