The keychain and the keystore are not the same kind of thing, and keystore means two different things.
Apple's keychain is an encrypted database that holds secrets and gives them back to your code. Android's Keystore system is a container for cryptographic keys that lets you use a key without ever reading it. Those are two different jobs, so any instruction that treats the words as synonyms is about to tell you something wrong. Then there is the third object, the one that costs real money: the file people call their keystore, which sits on a laptop, signs your Android app, and never goes near a phone. If somebody handed you a React Native and Expo project you did not type, all three are already in it. Every definition below comes from Apple's, Android's or Expo's own documentation, each read on 17 October 2026, and nothing here comes from a forum answer. Most people meet these words on the day they first try to ship, which is also the day they meet publishing to the App Store.
What follows is what each platform says about its own side, how to tell which of the three a given sentence means, what your inherited project already does with them, and the single mistake here that cannot be undone.
Start hereThe short version
Three objects, two words, and the dangerous one is a file.
Apple's one line summary of keychain services is to securely store small chunks of data on behalf of the user. You put a password in, your code asks for it later, and it comes back. Android's Keystore system is narrower on purpose. It holds cryptographic keys, and Android says the key material remains non-exportable. You can sign with the key. You cannot see it. The Android equivalent of dropping a password into the keychain is to encrypt the password yourself with a key from the Keystore system, which is exactly what the Expo library in your project does for you.
The third object is unrelated to either. Android Studio's app signing documentation defines a Java Keystore as a binary file that serves as a repository of certificates and private keys. It is not an API and it is not on the device. It is a file, with a password, that proves an update came from you. Android says that if you lose it you cannot regenerate it and cannot publish updates to your existing app. When a build log or a forum reply says keystore with no other context, this is the one it means.
What does Apple mean by the keychain?
A database. Apple's summary line for keychain services is “securely store small chunks of data on behalf of the user”, and the overview is more specific than that: the API gives your app a mechanism to store small bits of user data in an encrypted database called a keychain. Apple's keychain items page says the same thing from the other direction. Keychain services handles the data encryption and the storage in a keychain, which it calls an encrypted database stored on disk. Alongside the secret you supply a set of publicly visible attributes, which both control the item's accessibility and make it searchable.
What belongs in it is broader than the name suggests. Apple says the keychain is not limited to passwords. Its own examples of secrets the user explicitly cares about are credit card information and even short notes. It also covers things the user never sees: Apple names cryptographic keys and certificates in the same passage and says you use the keychain to store these items as well. One store, four kinds of thing. That is why Apple needs no second word for any of it, and it is the root of the mismatch, because Android splits the same ground across three names.
Hold on to one property, because it is the exact point where the two platforms part company. Apple's guidance on protecting keys with the Secure Enclave opens by agreeing that keeping a private key in a keychain is a good way to secure it, the key data being encrypted on disk and reachable only by your app or apps you authorise. Then it names the catch. To use the key, you must briefly copy a plain text version of it into system memory. The keychain gives the secret to your process, because that is what a secret store is for. Apple's answer for keys that must never be handed over is a different mechanism, the Secure Enclave, which it describes as a hardware based key manager isolated from the main processor, and which only works with NIST P-256 elliptic curve keys and cannot take in a key that already exists.
Which keystore is the instruction talking about?
There are two, documented in different places, and only one of them is on the phone. The on-device one is the Android Keystore system. Android's words: it lets you store cryptographic keys in a container to make them more difficult to extract from the device, and once keys are in the keystore you can use them for cryptographic operations with the key material remaining non-exportable. That is not a policy, it is an architecture. Android says key material never enters the application process. Plaintext, ciphertext and messages to be signed or verified are fed to a system process that does the work. If your app process is compromised, an attacker may be able to use your keys and still cannot extract them. Key material can also be bound to the secure hardware of the device, the Trusted Execution Environment or a Secure Element, and then it is never exposed outside that hardware at all.
Android adds a restriction Apple has no equivalent of. When you generate or import a key you declare its authorised uses, and Android says that once a key is generated or imported, its authorisations cannot be changed. Algorithms and purposes, padding and block modes, a window of time, whether the user must have authenticated recently. You choose at creation and you live with it. A key created without a user authentication requirement cannot be promoted into one later. You generate a new key and migrate what it protected, which is a real piece of work to discover halfway through a release.
Awkwardly, Android uses the word keychain too, which is most of why this never gets settled. Its page carries a section headed choose between a keychain and the Android Keystore provider, and the difference is scope. Use the KeyChain API when you want system-wide credentials: a system-provided interface then lets the user choose which of the installed credentials an app may access, so several apps can use one set with the user's consent. Use the Android Keystore provider to let one app store its own credentials, which only that app can reach and which need no dialog. An app built for a single business wants the second one, every time.
The second keystore has nothing to do with any of that. Android Studio's app signing page defines it in one sentence: Java Keystores, with a .jks or .keystore extension, are binary files that serve as repositories of certificates and private keys. Note that you already own one you never made. The self-signed certificate used to sign debug builds lives in debug.keystore under your home directory, and Android says it has an expiration date 30 years from its creation date, at which point your build simply fails. The fix is to delete the file and let the next debug build generate a replacement. That is the whole lifecycle of the harmless one. The release key is the same kind of object with none of the forgiveness.
Android Developers, the Android Keystore system, last updated 6 March 2026, read 17 October 2026
Sort it out
Which one are you looking at?
Pick what you were actually handed. The three objects answer to two words, so the fastest way through is to name the object first.
Nothing picked. If you are not sure which of the three a sentence means, the test is whether it mentions a file path or a password. A file path means the signing keystore every time.
What each of the three actually is
| The question | Apple's keychain | The Android Keystore system | Your keystore file |
|---|---|---|---|
| Where it lives | An encrypted database on the device | A system process on the device, optionally in secure hardware | A file on your computer, or inside Google's infrastructure |
| What it holds | Passwords, keys, certificates, short notes | Cryptographic keys, nothing else | Certificates and private keys |
| Your code can read the value back | Yes | No | Yes |
| Set up from inside the app | Yes | Yes | No |
| Losing it ends the app | No | No | Yes |
| Who documents it | Apple, keychain services | Android Developers, the Android Keystore system | Android Studio, sign your app |
The row that matters is the third one. On iOS your code can read the stored value back, which is the feature. On Android the key cannot be read, so the value has to be encrypted and parked somewhere else. Everything confusing about cross-platform secret storage follows from that one asymmetry, and no library hides it completely.
Do you have to care if you did not write the project?
In one place, yes, and it is already in the code. The Expo library for device-side secrets is expo-secure-store, and its own documentation, read on 17 October 2026, tells you it is not one behaviour but two. On iOS, values are stored using the keychain services as a generic password item. On Android, values are stored in SharedPreferences, encrypted with Android's Keystore system. That single pair of sentences is the bridge between the two halves of this page. The key never leaves the Android Keystore system, and the value it protects sits next door in ordinary preferences, unreadable only because the key is out of reach.
Both platforms then let you tighten it, with different words for the same intention. On iOS you set the item's kSecAttrAccessible attribute, which controls when the value is available to be fetched, and the library's default is the setting that allows access while the device is unlocked. Asking for biometrics maps to setUserAuthenticationRequired on Android, which needs API level 23, and to the current biometric set on iOS. Those names, defaults and platform minimums move between releases, so read the Expo SDK release notes for your version before you copy a snippet from anywhere, including from here.
The reason to look at all is that the choice was made without you. Nobody asked whether the session token should survive a lock screen. The engine your app runs on was settled the same way, which is what Hermes and the new architecture is about, and mostly you can leave that one alone. This one is different, because it is a security decision and the sensible default sits at the permissive end of the range. Reading the four lines that store your token is a ten minute job, and it is the only way to know what you are promising a customer.
There is also a ceiling nobody states as a firm number. Expo says large payloads can be rejected by the underlying platform, that historically some iOS releases refused values above roughly 2048 bytes, and that Expo itself enforces no limit, so you have to handle native errors if you plan to store very large strings. A long signed token is not a safe thing to put in here without something around it to catch the failure.
What does getting this wrong actually cost?
Three costs, in rising order. The first is a bug your testers report and you cannot reproduce. The two device stores behave differently when the app goes away, and Expo is explicit about both. On Android, data saved with its secure storage will not be preserved upon app uninstallation. On iOS it will persist across app uninstallations if the app is reinstalled with the same bundle ID, because of the way the iOS keychain manages stored credentials, and Expo adds that you should never rely on that. So a tester who deletes the app to get a clean slate comes back signed out on Android and signed in on iOS. Neither result is a defect in your code, and no amount of reading your own code will explain it.
The second cost is a restore that fails quietly. Expo warns that the Android Auto Backup system has to be configured to exclude its shared preferences entries, because the app's entries are deleted from the Android key store when the app is uninstalled, and after a restore nothing is left to decrypt them with. The backup dutifully puts the bytes back and nobody on earth can read them. If you treat device storage as a source of truth for anything you cannot ask the server for again, this is where that assumption breaks.
The third cost is the one with no fix. Android is blunt about the file. Your private key is required for signing all future versions of your app, and if you lose or misplace it you will not be able to publish updates to your existing app, and you cannot regenerate a previously generated key. Two dates travel with that. Android recommends a validity period of 25 years or more, and for Google Play the key you sign with must have a validity period ending after 22 October 2033, which Play enforces so that users can upgrade seamlessly. Play App Signing moves the risk rather than removing it: Google manages and protects the app signing key, you keep a separate upload key, and a lost or compromised upload key can be reset from the Play Console. The trade is that after you opt in you cannot retrieve a copy of the app signing key, and Google may keep a backup of it for disaster recovery.
One smaller cost is worth naming because it hides. Reading from either device store is an asynchronous call, and if your first screen waits for a token before it renders anything, that read is on the critical path for every cold launch. It is one of the things people are actually measuring when they talk about app startup time, and Android notes separately that cryptographic operations can be time consuming and should be kept off the main thread.
Android Developers, the Android Keystore system, last updated 6 March 2026, read 17 October 2026
Where this lands if a builder generated your app
Newly is an AI app builder. You describe an app in plain English and it writes a real React Native and Expo project you own, with two-way GitHub sync, so none of this is behind glass. It uploads iOS builds to TestFlight, publishes to Google Play internal testing and builds a standalone Android APK. It is $25 a month, with no free plan. It does not submit to the App Store for you, because Apple requires the owner of the content to submit.
What that means here is that the two halves have different owners. The device-side storage is in the code, in a repository you hold, so you can read the lines that save a token, see which accessibility setting they use, and change it. Nobody can do that part for you. Only you know whether a session should survive a locked phone, and whether a refresh token in your app is worth less than a password or rather more.
The signing key is the part to ask a direct question about instead of assuming. Something signed the APK that turned up, so a key exists somewhere. Find out three things while it is still cheap to ask: whether you hold the app signing key or Play App Signing does, whether what you hold is an upload key rather than the signing key itself, and whether the file and its passwords exist anywhere other than one machine. Android's warning only becomes expensive after version one has real installs, which is precisely when nobody has time to go looking.
The honest limit: no generator settles the policy questions on this page. Whether a token belongs behind a biometric prompt, whether a credential may outlive an uninstall, and who in your company is allowed to hold a signing key are decisions about your business and your risk, not about your framework. What a generator can do is stop them being invisible, which is most of the problem.
Questions people ask about the keychain and the keystore
No, and they do different jobs. Apple describes keychain services as a way to securely store small chunks of data on behalf of the user, in an encrypted database called a keychain. You put a password in and your code gets the password back. Android describes the Android Keystore system as a container for cryptographic keys that makes them more difficult to extract from the device, with the key material remaining non-exportable. You can sign or decrypt with a key in it, but you cannot read the key. One is a store of secrets, the other is a store of keys you are only allowed to use. Both pages read on 17 October 2026.
Describe the app, then go and find the key
Two jobs, neither of them long. Read the lines in your project that store a secret and decide whether the default is what you want. Then write down who holds the Android signing key and where its backup lives. Do both before you have users and neither one ever becomes a story.
Start building