Android System Design Interview Questions
What is the difference between symmetric and asymmetric encryption?
Tier: CommonDifficulty: Easy
Symmetric encryption uses the same key to encrypt and decrypt. Asymmetric encryption uses a linked public and private key pair. For encryption, the public key encrypts and the private key decrypts. Related algorithms can create signatures or agree on a shared secret, but the allowed operation depends on the algorithm.
- Symmetric, algorithms like AES. Fast and cheap enough to run on large amounts of data, which is why it's what actually encrypts the bulk of your traffic or a file on disk. The catch is key distribution. Both sides need the same secret, and getting it to the other party without it leaking is the whole problem.
- Asymmetric, algorithms like RSA, and increasingly elliptic curve ones, ECDSA and Ed25519 for signing, ECDH for key agreement, which get the same strength from far smaller keys. You can hand the public key out to anyone, and the reason it's safe is that there's no practical way to work back from the public key to the private one. That solves the distribution problem, at the cost of being much slower, so you never point it at bulk data.
Signing is the direction people forget, and on Android it's the more common one of the two. You sign a payload with the private key, and anyone holding the public key can check that it came from you and hasn't been altered on the way. Signing and encryption are distinct operations with different schemes, even when an algorithm family supports both.
Because of the speed gap, real systems don't pick one, they combine both. In TLS 1.3, the version securing the HTTPS calls your app makes now, the two sides run an ephemeral Diffie Hellman exchange, so each derives the same shared secret without either one ever putting it on the wire. The certificate's key isn't used to encrypt that secret, it's used to sign the handshake, which is how the server proves it's who the certificate says. The older design, where the client encrypted a secret to the server's RSA public key, was removed from the protocol in 2018. Once the shared secret exists, application traffic uses negotiated symmetric authenticated encryption such as AES-GCM or ChaCha20-Poly1305.
On Android, Keystore creates and holds keys for operations such as encrypting local data and signing requests. A key can be kept nonexportable, meaning the app can use it without reading its raw bytes. Decrypted data and allowed key operations still need protection. Hardware support depends on the device and key setup. StrongBox provides stronger isolation where available. setUserAuthenticationRequired can require the user to authenticate before the key is used.
How I'd build this on Android
I'd distinguish encryption, signatures and key agreement. An asymmetric algorithm does not necessarily do all three. ECDSA and Ed25519 create signatures. ECDH lets two parties agree on a shared secret. RSA supports specific encryption and signature schemes. Signing is not simply encrypting with the private key.
// A device-local authenticated-encryption key, generated once per alias.
val generator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore")
generator.init(KeyGenParameterSpec.Builder(
"notes-storage-key",
KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT,
).setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.build())
val key = generator.generateKey()
val cipher = Cipher.getInstance("AES/GCM/NoPadding")
cipher.init(Cipher.ENCRYPT_MODE, key)
val ciphertext = cipher.doFinal(plaintext)
val nonce = cipher.iv // Store with ciphertext. Never reuse a nonce with this key.
This example shows one encryption operation. A real app loads an existing key alias instead of generating a new key for every write. It saves the algorithm version and nonce, checks whether the key is still usable and handles failed authentication checks. The repository receives an encrypted storage interface. Room saves the encrypted record and its metadata. Raw keys never go into WorkManager input. Large files need a reviewed streaming encryption format instead of one giant byte array.
Keystore can prevent the app from exporting a raw key. A compromised app process may still ask that key to perform allowed operations or read data after decryption. Hardware protection depends on the device and key setup. A key stored on one device does not automatically work on another. I'd either exclude the encrypted data from backups or define how it can be recovered with the right key.
I'd check these cases.
- Changed ciphertext.
- An invalidated key.
- Restore on another device.
- A key that requires user authentication while the device is locked.
TLS may use AES GCM or ChaCha20 Poly1305, so I would not claim every encrypted connection uses AES. See Android Keystore.
Read more Cryptography (opens in a new tab)Android Keystore system (opens in a new tab)