How to Implement a Secure Pattern Lock for Mobile Apps
Pattern lock — an Android original, less common on iOS (no system equivalent). It works like a PIN: local device unlock without sending the secret to the server. But the pattern has specific security issues you must understand before implementation. Our experience with mobile authentication (over 20 projects) shows: a proper implementation with the right crypto stack makes the pattern convenient and secure enough for most scenarios.
Security Considerations
Why is Pattern Lock Vulnerable to Shoulder Surfing?
Finger smudges remain on the screen. Research by Abraham and colleagues (2010) showed that most users draw L-, Z-, or S-shaped patterns — the 12 most popular patterns cover ~20% of the user base. A 9-dot pattern can be visually reconstructed from 1–2 meters under the correct lighting angle. In our practice, we use a line-hiding timer and fade animation to minimize leakage.
How is the Pattern Encoded and Cryptographically Protected?
Standard 3×3 grid — 9 dots indexed 0–8. The pattern is a sequence of indices. Minimum length is 4 dots (Android requirement). From 9 dots with minimum length 4, about 389,112 possible patterns — significantly fewer than a 6-digit PIN (1,000,000 combinations). PIN provides 2.5 times more combinations.
We encode the pattern into an index string: [0,1,2,5,8] → "01258". This string is used as input for key derivation — same PBKDF2 scheme as for PIN. Never store the pattern in plaintext. Store the derived key in Keychain (iOS) or EncryptedSharedPreferences (Android).
More about the cryptographic scheme
PBKDF2 with salt and 100,000 iterations — minimum threshold. On Android, we additionally encrypt using Android Keystore; on iOS, Secure Enclave. This ensures protection even if the device is compromised.Platform-Specific Implementation
Custom View with Jetpack Compose (Android)
On Android, you can use com.github.itsxtt:pattern-lock or similar open-source libraries for basic line drawing. But in enterprise projects, we write our own: full control over visuals, cryptography, and no dependency on unsupported libraries.
@Composable fun PatternLockView( onPatternComplete: (List<Int>) -> Unit ) { val selectedDots = remember { mutableStateListOf<Int>() } var currentPosition by remember { mutableStateOf(Offset.Zero) } Canvas( modifier = Modifier .fillMaxSize() .pointerInput(Unit) { detectDragGestures( onDragStart = { offset -> /* find nearest dot */ }, onDrag = { change, _ -> currentPosition = change.position // add dot if within radius }, onDragEnd = { if (selectedDots.size >= 4) onPatternComplete(selectedDots.toList()) selectedDots.clear() } ) } ) { // draw dots and lines between selectedDots plus line to currentPosition } } Key details: a dot can be visited only once; a line crossing an untouched dot automatically adds it (standard Android Pattern Lock behavior); minimum touch distance to a dot is ~24dp. We hide the pattern after 500–800 ms — lines disappear, dots remain. This prevents shoulder surfing.
Custom Implementation via SwiftUI (iOS)
iOS has no system Pattern Lock. We implement using SwiftUI Canvas + DragGesture. Analogous logic, visuals adapted to iOS Human Interface Guidelines. On iOS, pattern lock is rarer — usually a specific client request (e.g., children's apps or specialized enterprise tools). We guarantee seamless integration with biometrics (Face ID / Touch ID) and, if needed, custom UI animations.
How to Implement Pattern Lock on Both Platforms
- Design UX pattern: minimum length, timers, animations.
- Implement custom View (Compose/SwiftUI) with gesture handling.
- Integrate cryptographic protection: PBKDF2, secure container storage.
- Integrate with biometrics and fallback login.
- Document code and describe the scheme.
- Test on real devices (minimum 5 models).
- Provide post-implementation support (2 weeks).
Pattern vs PIN: When to Use Which
| Criterion | Pattern (3×3) | PIN (6 digits) |
|---|---|---|
| Combinations | ~389,112 (min 4 dots) | 1,000,000 |
| Shoulder surfing resistance | Vulnerable, need protection | Moderate |
| Ease of input | High, intuitive | Medium |
| Recommendation | For low-sensitivity apps | For banks, medical data |
Pattern login is convenient for low-security apps like trackers or organizers. For banking, medical, or corporate access, we recommend a PIN of 6+ digits with PBKDF2 or biometrics.
Fallback and Error Handling
After 5 failed attempts — require full login via credentials. The failure counter is stored in Keychain (iOS) or EncryptedSharedPreferences (Android). After successful login, reset the counter and offer to redraw the pattern — important to warn the user that the old pattern is reset. This mechanism is mandatory to protect against brute force.
Deliverables and Timeline
What’s Included in the Work
- UX design: minimum length, timers, animations.
- Custom View implementation (Compose/SwiftUI).
- Cryptographic protection: PBKDF2, secure storage.
- Integration with biometrics and fallback login.
- Complete source code with documentation.
- Access to private repository (GitHub/GitLab).
- Training session for your team (1 hour).
- Testing on at least 5 real device models.
- Post-implementation support for 2 weeks.
Estimated Timeline and Cost
Custom Pattern Lock with proper cryptographic scheme on one platform — 5–8 business days. On both platforms — 10–14 days (with UX adaptation for each OS). Typical cost starts at $500 per platform and can go up to $1,500 depending on integration complexity. We evaluate your project for free — contact us to discuss details.







