惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园_首页
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog
B
Blog RSS Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
P
Proofpoint News Feed
MyScale Blog
MyScale Blog
Engineering at Meta
Engineering at Meta
量子位
H
Hackread – Cybersecurity News, Data Breaches, AI and More
T
Tailwind CSS Blog
Stack Overflow Blog
Stack Overflow Blog
N
Netflix TechBlog - Medium
T
The Blog of Author Tim Ferriss
U
Unit 42
aimingoo的专栏
aimingoo的专栏
博客园 - 叶小钗
博客园 - 【当耐特】
云风的 BLOG
云风的 BLOG
博客园 - Franky
博客园 - 聂微东

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
How offline license activation actually works
Nico · 2026-06-27 · via DEV Community

Nico

If you ship a desktop app outside an app store, you eventually hit the same wall: how do you check a license when the user is on a plane, behind a corporate firewall, or just offline? Calling your server on every launch isn't an option. Here's how offline activation actually works, without the hand-waving.

The naive version, and why it breaks

The first thing everyone reaches for is "call home on launch, get back yes/no." It works in the demo and fails in the wild:

  • No network = no app. Fail-closed locks out paying customers. Fail-open means anyone who blocks your domain runs free. Both are bad.
  • A boolean is forgeable. If your app trusts a {"valid": true} response, a proxy or a patched DNS entry returns that for free.

The fix isn't a better endpoint. It's moving the trust off the network and onto cryptography.

The model that works: signed leases

The durable pattern is a cryptographically signed lease (Keygen calls these license files, Keylight calls them leases — same idea):

  1. On first activation, the device talks to the server once.
  2. The server returns a small signed document: the license state, an expiry, the device binding, and any entitlements (which features/tiers are unlocked).
  3. The document is signed with the server's private key (Ed25519 is the modern choice — small, fast, boring in the good way).
  4. Your app ships the matching public key and verifies the signature locally on every launch. No network needed.

Because the app only ever verifies with a public key, there's nothing secret in the binary to steal, and a forged lease fails the signature check. That's the whole trick: the server vouches once, math vouches forever after.

first launch ──► server signs lease (Ed25519, private key) ──► stored on device
every launch ──► app verifies signature (public key) ──► no network

Device binding (so one key isn't infinite installs)

A lease is bound to a device so a single license can't be pasted onto a thousand machines. The lease embeds a device fingerprint, and the SDK checks the running machine matches. The honest engineering note: fingerprints drift. macOS hardware UUIDs are stable; "hostname + user" is not. Pick a stable identifier and give users a deactivate path, or you'll drown in "I reinstalled and now I'm locked out" tickets.

The tradeoff nobody mentions: revocation vs. offline

Here's the tension you have to design around deliberately. A purely offline lease can't be revoked instantly — that's the point, it doesn't phone home. So a refunded or charged-back user keeps a valid lease until it expires.

You resolve it with a max-offline window. The lease carries an expiry (say 7, 14, 30 days). Inside the window, fully offline. Past it, the app must revalidate online once to refresh the lease — which is your chance to revoke. Short window = tighter control, more online checks. Long window = friendlier offline story, slower revocation. There's no universally right number; it depends on your price point and abuse surface.

What this looks like with an SDK

You don't want to hand-roll Ed25519 and lease parsing. Most licensing SDKs hide this behind a couple of calls. With Keylight, for example, the offline path collapses to: activate once, then a local checkOnLaunch() that verifies the lease and hands you a state — licensed, trial, expired, invalid — with no network call. Entitlements ride inside the signed lease, so feature gating is offline too. Keygen, Cryptolens, and LicenseSpring implement the same primitive with different ergonomics; the underlying cryptography is the part that matters and it's the same everywhere.

The takeaway

Offline activation isn't "cache the server's answer." It's: trust the network once, trust signatures forever after, bind to a stable device id, and pick a max-offline window that matches how fast you need to revoke. Get those four right and your app works on a plane and still says no to a refunded license.

If you're building this for a Mac or Tauri/Electron app and don't want to implement the crypto yourself, I wrote up the Keylight offline verification model here.