You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: implement integrity hardening for sensitive data storage
- Added HMAC-SHA256 integrity tags to entries, enhancing tamper detection.
- Introduced AES-GCM AAD for additional security against cross-entry attacks.
- Implemented zeroization of plaintext buffers post-use on both platforms.
- Updated error handling to include IntegrityViolationError for tampering cases.
- Enhanced metadata structure to include integrity tags and AAD usage flags.
- Updated tests to verify integrity tag propagation and error handling for integrity violations.
Co-authored-by: Copilot <copilot@github.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,6 +3,13 @@
3
3
### Features
4
4
5
5
***rotation:** Add versioned key rotation via `rotateKeys()` and `getKeyVersion()` with lazy re-encryption on read. New `useKeyRotation` hook exposes the same flow declaratively.
6
+
***security hardening:** Defense-in-depth pass — non-breaking, applied transparently to new writes and via lazy upgrade on rotation:
7
+
- HMAC-SHA256 integrity tag bound to every entry's metadata + ciphertext, surfaced on `StorageMetadata.integrityTag`. Tampering with SharedPreferences/Keychain attributes now raises `IntegrityViolationError` (`E_INTEGRITY_VIOLATION`) before any biometric prompt is shown.
8
+
- AES-GCM AAD on Android binds ciphertext to `service|key|v<version>`, defeating cross-entry swap attacks.
9
+
-`setUnlockedDeviceRequired(true)` on every Android Keystore key (API 28+), mirroring iOS's `kSecAttrAccessibleWhenUnlocked` semantics.
10
+
- Plaintext byte buffers are zeroized after use on both platforms.
- Backwards compatible: entries written by earlier versions decode without verification and are upgraded on the next write or rotation.
6
13
***errors:** New typed error classes (`SensitiveInfoError`, `NotFoundError`, `AuthenticationCanceledError`, `IntegrityViolationError`, `KeyInvalidatedError`, `RotationFailedError`) with `code` discriminants and `instanceof` predicates. Importable from the `react-native-sensitive-info/errors` subpath.
7
14
***tree-shaking:**`"sideEffects": false` everywhere; the package now publishes three focused subpath entries (`.`, `/hooks`, `/errors`). The default export has been removed — import only the helpers you use.
8
15
***nitro 0.35:** Regenerated against `nitrogen@0.35.5` and `react-native-nitro-modules@0.35.5`.
| Error classification | Typed `SensitiveInfoError` subclasses via `/errors` subpath | Same |
314
317
318
+
> **Tamper detection:** every read recomputes the HMAC over the persisted `(service, key, version, accessControl, securityLevel, timestamp, ciphertext, iv)` tuple. A mismatch raises `IntegrityViolationError` (`E_INTEGRITY_VIOLATION`) **before** any biometric prompt fires, so spoofed entries can never trigger user authentication. Entries written by older library versions (no `integrityTag`) are accepted on first read and upgraded on the next write or rotation.
319
+
315
320
Typed errors can be imported from the `/errors` subpath for tree-shakeable error handling:
0 commit comments