npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@motebit/crypto-android-keystore

v1.1.2

Published

Apache-2.0 verifier for Android Hardware-Backed Keystore Attestation hardware-attestation credentials — offline X.509 chain verification against pinned Google Hardware Attestation roots (RSA-4096 + ECDSA P-384), plus ASN.1 extraction of the KeyDescription

Readme

@motebit/crypto-android-keystore

Offline Apache-2.0 verifier for Android Hardware-Backed Keystore Attestation hardware-attestation credentials.

npm i @motebit/crypto-android-keystore

Plugs into @motebit/crypto's HardwareAttestationVerifiers dispatcher as the androidKeystore verifier — called when a credential declares platform: "android_keystore" (Android devices with KeyMaster 3+ / KeyMint 1+ — every modern Android device since Android 7).

Usage

import { verify } from "@motebit/crypto";
import { androidKeystoreVerifier } from "@motebit/crypto-android-keystore";

const result = await verify(credential, {
  hardwareAttestation: {
    androidKeystore: androidKeystoreVerifier({
      // Bytes of the registered Android package's `attestationApplicationId`,
      // captured at registration time. Must byte-equal what the leaf
      // attestation extension reports.
      expectedAttestationApplicationId,
    }),
  },
});

What it verifies

  1. Cert chain to a pinned Google Hardware Attestation root. Two roots ship pinned: the legacy RSA-4096 root (for factory-provisioned devices) and the modern ECDSA P-384 root (for RKP-provisioned devices). Verifiers MUST pin both — Google rotated from RSA to ECDSA between Feb–Apr 2026, so a verifier pinning only one drops half its install base.
  2. The Android Key Attestation extension (OID 1.3.6.1.4.1.11129.2.1.17) on the leaf — attestationVersion ≥ 3 (Keymaster 3 / Android 7+), attestationSecurityLevel ≥ TRUSTED_ENVIRONMENT (rejects software-only fallback), hardwareEnforced.rootOfTrust.verifiedBootState in caller's allowlist (default [VERIFIED]), hardwareEnforced.attestationApplicationId byte-equals the registered package binding.
  3. Optional revocation snapshot. Caller-supplied snapshot keyed by lowercase-hex serial number, mirroring Google's published shape at https://android.googleapis.com/attestation/status. Defaults to empty (no revocation enforcement). The verifier never fetches at runtime — @motebit/verify ships an embedded snapshot at release time.
  4. Identity binding. The leaf's attestationChallenge must byte-equal SHA-256(canonicalJson({ attested_at, device_id, identity_public_key, motebit_id, platform: "android_keystore", version: "1" })) — the same body the Kotlin expo-android-keystore mint path composes. A malicious client that substitutes any other body fails here.

Why pinned

A verifier that dynamically fetched Google's attestation roots has no sovereign story. The pinned roots are the self-attesting contract — third parties audit DEFAULT_ANDROID_KEYSTORE_TRUST_ANCHORS and know which trust anchors this library accepts. Source of truth: roots.json in android/keyattestation, Google's canonical Kotlin reference verifier.

Why a hand-rolled DER walker

The KeyDescription ASN.1 structure has ~50 optional context-tagged fields in AuthorizationList, two of which carry policy-relevant material ([704] rootOfTrust and [709] attestationApplicationId). A schema-driven parser would have to declare all 50 fields just to skip past the ones we ignore. Walking the DER directly costs ~150 lines and stays scoped to exactly what verification needs — same trade-off @motebit/crypto-tpm made for TPMS_ATTEST parsing.

Privacy posture

Closer to FIDO Yubico-batch than to TPM EK. The leaf X.509 subject is the fixed string CN=Android Keystore Key — not device-identifying. The optional ID-attestation family (attestationIdSerial, attestationIdImei, etc.) only fires when the caller invokes setDevicePropertiesAttestationIncluded(true); motebit does not. Default setAttestationChallenge() produces batch-shareable chains with the device-identifying material confined to (a) the caller-controlled challenge and (b) verifiedBootKey (boot-image identity, not user identity).

Related

License

Apache-2.0 — see LICENSE and NOTICE.

"Motebit" is a trademark. The Apache License grants rights to this software, not to any Motebit trademarks, logos, or branding. You may not use Motebit branding in a way that suggests endorsement or affiliation without written permission.