🔑 KeyLens
Inspect Android keystores, iOS provisioning profiles and app signatures — without leaving VS Code.
No keytool. No openssl. No security cms -D -i. No JDK required.
Why
Every mobile release runbook contains the same three moments of friction:
- "Firebase wants the SHA-1 of the debug keystore." →
keytool -list -v -keystore … | grep SHA1
- "Which keystore matches the fingerprint in the Play Console?" → open every
.jks you can find
- "Why won't this build install?" → the provisioning profile expired last Tuesday
KeyLens turns all three into a click. Point it at a file — or let it scan your workspace — and it reads
the signing material directly, in pure Node, and shows you exactly what you need.
Features
🔍 Reads every signing artifact a mobile project contains
| Format |
What you get |
.jks / .keystore (JKS & JCEKS) |
Every alias, its certificate chain, creation date, fingerprints — no store password required |
.p12 / .pfx (PKCS#12) |
Aliases, friendly names, key algorithm, full certificate details |
.pem / .cer / .crt / .der |
Certificate chains and bundles |
.mobileprovision / .provisionprofile |
Team, App ID, type (development / ad-hoc / App Store / enterprise), entitlements, provisioned devices, expiry, embedded developer certificates |
.apk / .aab |
Signature schemes (v1 / v2 / v3 / v3.1), signer certificates, application ID, version, min/target SDK |
.ipa |
Embedded provisioning profile, App ID, expiry |
📋 The fingerprints you actually need, one click away
SHA-1, SHA-256 and MD5 in keytool format, plus the Base64 SPKI pin for OkHttp / TrustKit — each
labelled with what it's for (Firebase, Google Sign-In, Maps, Play App Signing, App Links).
🎯 "Which keystore is this?"
Paste a fingerprint from the Play Console, Firebase or App Store Connect and KeyLens tells you which
file in your workspace it belongs to — and which alias inside it.
⏰ Expiry, before it bites
A workspace-wide expiry sweep, a status-bar warning when something is running out, and a check for
Google Play's "upload keys must be valid until 22 October 2033" rule.
🩺 Signing hygiene findings
Weak keys (RSA < 2048), SHA-1 signatures, debug keys in a release artifact, v1-only APKs,
get-task-allow on a distribution profile, push-environment mismatches.
🤖 GitHub Copilot integration
Chat participant — ask @keylens in natural language:
@keylens /inspect app/release.jks
@keylens /fingerprint → the SHA-1 Firebase is asking for
@keylens /expiry → everything that expires, soonest first
@keylens /match A1:B2:C3:… → which keystore is this?
Agent-mode tools — Copilot can call keylens_inspectSigningArtifact, keylens_listSigningArtifacts
and keylens_matchFingerprint on its own while working on your build files, or you can reference them
directly with #signingArtifact, #signingArtifacts and #fingerprintMatch.
Getting started
- Install KeyLens.
- Open the KeyLens view in the activity bar — it scans your workspace for signing material.
- Click any artifact to open the inspector.
Or run KeyLens: Inspect Signing Artifact… from the command palette, or right-click any keystore,
profile or package in the Explorer → Inspect with KeyLens.
Commands
| Command |
What it does |
KeyLens: Inspect Signing Artifact… |
Open any signing file in the inspector |
KeyLens: Scan Workspace for Signing Artifacts |
Find every keystore, profile and package |
KeyLens: Copy SHA-1 / SHA-256 / MD5 Fingerprint |
Straight to the clipboard |
KeyLens: Copy SPKI Pin (Base64) |
For certificate pinning |
KeyLens: Match Fingerprint Against Workspace… |
Identify a fingerprint from a console |
KeyLens: Check Expiry of All Artifacts |
Markdown expiry report |
KeyLens: Export Certificate as PEM… |
Save one certificate or the whole chain |
KeyLens: Export Signing Report (Markdown)… |
Shareable report for a release ticket |
KeyLens: Generate Gradle signingConfig Snippet |
Kotlin or Groovy DSL, credentials via env vars |
KeyLens: Forget Cached Keystore Passwords |
Clear anything remembered this session |
Settings
| Setting |
Default |
Description |
keylens.autoScan |
true |
Scan the workspace on activation |
keylens.scanExclude |
node_modules, build/intermediates, DerivedData, Pods, .git |
Globs excluded from the scan |
keylens.maxScanResults |
200 |
Cap on scan results |
keylens.warningThresholdDays |
30 |
When to start warning about expiry |
keylens.defaultPasswords |
android, changeit, `` |
Tried automatically before prompting |
keylens.rememberPasswords |
false |
Persist passwords in the OS keychain (opt-in) |
keylens.fingerprintCase |
upper |
Case for copied fingerprints (keytool prints uppercase) |
Privacy & security
- Everything is local. KeyLens never sends your keys, certificates or fingerprints anywhere.
The only network-capable feature is the optional Copilot chat, which sends parsed metadata only when
you start a conversation.
- Private keys are never decrypted. KeyLens reads certificates and metadata; the encrypted key
material in a keystore is skipped over, not unlocked.
- Passwords stay in memory for the session unless you explicitly enable
keylens.rememberPasswords,
which stores them in the OS keychain via VS Code SecretStorage — never in settings or workspace state.
How it works
KeyLens implements the container formats directly in TypeScript rather than shelling out:
- JKS / JCEKS — the OpenJDK keystore layout, including the trailing keyed SHA-1 digest, so a store
password can be verified and certificate chains can be read without one.
- APK Signing Block — walked pair by pair to detect v2 / v3 / v3.1 signers, with the legacy
META-INF/*.RSA PKCS#7 blob parsed for v1.
- Binary AndroidManifest.xml — enough of Android's AXML format to resolve the application ID and
version, including resource-map fallback when attribute names are stripped.
- Provisioning profiles — the XML plist extracted from its CMS wrapper and parsed in-process.
- PKCS#12 — the one format that genuinely needs the legacy ciphers, handled with
node-forge.
Output is verified against keytool and apksigner: same fingerprints, same bytes.
Development
npm install
npm run watch # esbuild in watch mode, then press F5 for an Extension Development Host
npm run test:unit # parser + analysis tests on plain Node
npm run test:integration # activates the extension in a real VS Code instance
npm run package # produce the .vsix
test/fixtures/ holds throwaway keystores, a PKCS#12 bundle, a CMS-signed provisioning profile and a
v1-signed package — the fixture README documents how each was generated and the passwords. The unit
tests assert fingerprints that were cross-checked against keytool and apksigner; the integration
tests open that folder as a workspace and drive the real commands.
Companion extension
Working on TLS instead of signing? SSLens
is the same idea for live SSL/TLS certificates — chain inspection, expiry monitoring and pinning code
generation for OkHttp, Alamofire, Dio and friends.
License
MIT © Sitharaj