Skip to content

Instantly share code, notes, and snippets.

@schirrmacher
Created March 6, 2020 15:21
Show Gist options
  • Save schirrmacher/00a672534056b95c3807a9ec0b2075c5 to your computer and use it in GitHub Desktop.
Save schirrmacher/00a672534056b95c3807a9ec0b2075c5 to your computer and use it in GitHub Desktop.
SafetyNet Attestation Example Implementation for Validating Device Authenticity on Android
import android.content.Context
import android.util.Base64
import com.google.android.gms.safetynet.SafetyNet
import inject.AppContext
import inject.modules.GoogleServicesModule.GoogleContext
import io.reactivex.Single
import java.io.ByteArrayOutputStream
import javax.inject.Inject
interface SecurityHelper {
fun verifyDevice(nonceInfo: String): Single<Result<String>>
}
class GoogleSecurityHelper @Inject constructor(
@AppContext private val context: Context,
@GoogleContext private val appKey: String
) : SecurityHelper {
override fun verifyDevice(nonceInfo: String): Single<Result<String>> =
Single.create<Result<String>> { emitter ->
try {
SafetyNet.getClient(context).attest(createNonce(nonceInfo), appKey)
.addOnCompleteListener { taskResult ->
if (emitter.isDisposed.not()) {
val jwsResult = taskResult.result?.jwsResult
val exception = taskResult.exception
val deviceValidationResult = when {
jwsResult != null -> Result.success(jwsResult)
exception != null -> Result.failure(exception)
else -> Result.failure(IllegalArgumentException())
}
emitter.onSuccess(deviceValidationResult)
}
}
} catch (e: Exception) {
if (emitter.isDisposed.not())
emitter.onSuccess(Result.failure(e))
}
}
private fun createNonce(nonceInfo: String): ByteArray = ByteArrayOutputStream()
.apply {
write(/* some nonce bytes */)
}.run {
toByteArray()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment