microg/GmsCore · error · StandardIntegrityException

Null deviceKeyMd5.

Error message

Null deviceKeyMd5.

What it means

ExpressIntegrityService.warmUpIntegrityToken throws with this message when the MD5 hash of the device key cannot be computed or is missing from the integrity payload, preventing construction of the device-integrity record for the express integrity response.

Source

Thrown at vending-app/src/main/kotlin/com/google/android/finsky/expressintegrityservice/ExpressIntegrityService.kt:169

                val creationTime = tokenWrapper.deviceIntegrityWrapper?.creationTime ?: Timestamp()
                val lastManualSoftRefreshTime = tokenWrapper.lastManualSoftRefreshTime ?: Timestamp()

                val deviceIntegrityAndExpiredKey = DeviceIntegrityAndExpiredKey(
                    deviceIntegrity = DeviceIntegrity(
                        tokenClientKey, deviceIntegrityWrapper.deviceIntegrityToken, creationTime, lastManualSoftRefreshTime
                    ), expressFilePB.expiredDeviceKey ?: ClientKey()
                )

                val deviceIntegrity = deviceIntegrityAndExpiredKey.deviceIntegrity
                if (deviceIntegrity.deviceIntegrityToken?.size == 0 || deviceIntegrity.clientKey?.keySetHandle?.size == 0) {
                    throw StandardIntegrityException("DroidGuard token is empty.")
                }

                val deviceKeyMd5 = Base64.encodeToString(
                    deviceIntegrity.clientKey?.keySetHandle?.md5()?.toByteArray(), Base64.NO_PADDING or Base64.NO_WRAP or Base64.URL_SAFE
                )
                if (deviceKeyMd5.isNullOrEmpty()) {
                    throw StandardIntegrityException("Null deviceKeyMd5.")
                }

                val deviceIntegrityResponse = DeviceIntegrityResponse(
                    deviceIntegrity, false, deviceKeyMd5, deviceIntegrityAndExpiredKey.expiredDeviceKey
                )

                val packageInfo = context.packageManager.getPackageInfoCompat(
                    expressIntegritySession.packageName, PackageManager.GET_SIGNING_CERTIFICATES or PackageManager.GET_SIGNATURES
                )
                val certificateSha256Hashes = packageInfo.signaturesCompat.map {
                    it.toByteArray().sha256().encodeBase64(noPadding = true, noWrap = true, urlSafe = true)
                }

                val packageInformation = PackageInformation(certificateSha256Hashes, packageInfo.versionCode)
                val clientKeyExtend = buildClientKeyExtend(context, expressIntegritySession, packageInformation, clientKey)
                val intermediateIntegrityRequest = IntermediateIntegrityRequest.Builder().apply {
                    deviceIntegrityToken(deviceIntegrityResponse.deviceIntegrity.deviceIntegrityToken)
                    readAes128GcmBuilderFromClientKey(deviceIntegrityResponse.deviceIntegrity.clientKey)?.let {

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Retry warm-up to obtain a well-formed client key
  2. Validate the session key material before finalizing the token wrapper
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at vending-app/src/main/kotlin/com/google/android/finsky/expressintegrityservice/ExpressIntegrityService.kt:169 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/ece3acdbe48584ab. Report an issue: GitHub.