We believe that the most secure mobile crypto wallet is one that overcomes the inherent constraints of its mobile operating system. For instance, on iOS, Apple’s CryptoKit doesn’t support the secp256k1 elliptic curve, a standard for Bitcoin, Ethereum and many other blockchains.
This limitation restricts developers from utilizing the secure element of devices for key storage and transaction signing. As a result, mobile crypto wallets are classified as hot wallets since they are both connected to the internet and sign transactions outside of a secure element using a software implementation of the cryptographic algorithms.
This means that the private keys must be exposed – at least during signing – within the memory of the sandboxed app environment. This leaves them more exposed to potential threats than a wallet which uses a secure element to sign transactions.
Despite the inability to perform the signing on the secure elements directly, which would offer increased protection, we have committed to providing an open-source mobile crypto wallet that prioritizes security, transparency and user control.
Our security architecture is purpose-built to:
Support multiple blockchains
Generate private keys with high entropy, a measure of unpredictability that bolsters security
Leverage battle-tested cryptography to securely encrypt users’ private keys, capitalizing on mobile phones’ security hardware and OS security features
Offer enhanced security with a user-generated password for advanced users who desire an additional level of encryption (on top of the OS keychain protection for the decryption key)
Create a solid foundation for future incorporation of new key management types, such as hardware wallets and MPC quorum-based systems
The open-source advantage
As one of its fundamental security principles, Kraken Wallet is free and open-source software, distributed under the MIT license. Building a new wallet from the ground up, it was important to us to help foster the open source and distributed ecosystem.
Without open-source code, Kraken Wallet would require a large amount of trust without transparency. This would give clients less protection; you couldn’t verify, modify or run the client by yourself if you wanted to. “Don’t trust, verify!” is not just an industry maxim, it’s one of our guiding principles.
Open sourcing our software fulfills two fundamental goals we initially set for this product: verifiable, auditable trust minimization:
Verifiability: The ability to verify that the security assumptions presented in this blog post are true. Anyone can look at the source code to specifically understand what is and is not being done in this wallet.
Auditability: The ability to verify that the output of our security implementation is correct and report back when it is not. We have engaged internal and external teams to perform security audits multiple times prior to release. Going forward, anyone can audit the code and produce a report on their findings.
Key generation and key import
React Native, while a powerful tool, does not have a built-in crypto module. To navigate around this we used a pure-js implementation (crypto-browserify) of NodeJS’s crypto module. The crypto.randomBytes() method – which generates the actual random bytes we require during key generation – is handled by the react-native-get-random-values polyfill.
React-native-get-random-values uses native code to utilize the Cryptographically Secure Pseudorandom Number Generator (CSPRNG) available on the device to generate random numbers. On practically all modern devices, this random number generator is backed by a secure hardware random number generator.
During wallet initialization, we draw entropy from the CSPRNG and convert it into a mnemonic seed using well-established npm packages (BIP32, BIP39).
Keys are converted, stored and presented to the user under the BIP39 standard, which offers an easy-to-backup mnemonic method with interoperability for most wallets in the ecosystem. The import feature supports recovery of BIP39 compatible seeds, which provide the best interoperability in the ecosystem.
Key management
Kraken Wallet holds two secret values – the seed and the mnemonic – and multiple non-secret (but still private) values such as wallet addresses, wallet names and descriptions of transactions.
Private key material (seed/mnemonic) is stored in Keychain (on iOS) and Keystore (on Android). Public key material and non-sensitive data (extended public keys, addresses and descriptions) are stored in the application’s encrypted database (using Realm).
There are multiple security controls protecting the data:
App lock: A randomly generated 64-byte string stored in Keychain or Keystore. Access to the secret is protected with user-presence requirements – biometric or passcode authentication.
Password: User-provided and not kept on a device. Instead, the user must provide the password manually whenever asked by the application. The wallet determines whether the password is needed by consulting two flags (is_storage_encrypted and is_seed_encrypted) stored in Keychain or Keystore. The Argon2 algorithm is used as a key derivation function.
Database encryption: The database (Realm) is used to store non-secret data. The data is encrypted with a random 64-byte key.
Lockout mechanism: Entering an incorrect password triggers delays before subsequent password attempts can be made. This mechanism effectively deters brute-force password attacks. Information regarding lockout parameters, such as the number of attempts and the duration of delays, is securely stored in Keychain or Keystore.
The seed, mnemonic and database encryption key are always stored in encrypted form
When no protections are enabled: The seed, mnemonic and Realm encryption key are stored directly in Keychain or Keystore without a user-presence access control.
When app lock is activated: The mnemonic and seed are first encrypted with the app lock secret and then securely stored in Keychain or Keystore. The Realm encryption key is also directly stored in the Keychain or Keystore.
When password protection is enabled: The mnemonic and seed are encrypted with the password, whereas the Realm encryption key is encrypted with the password only if is_storage_encrypted was set to true.
When both app lock and password protection are enabled: The mnemonic and seed are encrypted with both a password (first) and app lock (second). The Realm encryption key is encrypted only with the password and only if is_storage_encrypted was set to true.
Key usage
The seed/mnemonic is stored in Keychain or Keystore and plays a crucial role in cryptographic operations. When a new wallet address needs to be generated or a transaction needs to be signed, we derive the necessary information, such as the private key, from this seed.
However, it’s important to note that the private key must be loaded into memory during these operations. This necessity stems from the constraints we mentioned earlier about mobile wallets and the lack of direct access to the secure element for transaction signing.
Transaction signing (sending tokens)
WalletConnect data signing (handling session requests)
Adding a new wallet
Enabling testnet chains (adding testnet wallets)
Displaying the mnemonic
Verifying the mnemonic
Enabling and disabling app lock
Enabling and disabling the password
Additional biometric authentication is performed for the following functionalities:
Enabling app lock
Wiping all data
Deleting a wallet (account)
Enabling or disabling a password (in addition to the app lock retrieval)
Opening the application
Moving the application to the foreground
Viewing extended public keys
Connecting to a decentralized application (dApp)
Additionally, the password may be required for opening the application. Keychain and Keystore are always used through the react-native-keychain wrapper:
The wrapper generates a new key in Keychain or Keystore for every item
The wrapper is responsible for passing the correct configuration flags for Keychain and Keystore
The wallet always requests the wrapper to configure the flags so that the device must be unlocked to access the key
A user-presence (biometric) check is configured to be time-based, and the check is valid for 5 seconds; the user-presence check is not performed per access
The encryption algorithm is the same for all items:
The key is derived with Argon2id from an NFC-normalized secret
The salt for Argon2id is the device’s unique ID
The encryption mode is AES-GCM
The initialization vector (IV) for AES is 16 random bytes
The auth tag for AES is required to be 16 bytes long
Transaction signing
In addition to the previously mentioned measures regarding key storage, biometrics and password protection, transaction signing remains a critical area of focus for continuous improvement. As an initial step, we have implemented several noteworthy measures in this domain, including:
Transaction simulation
We use external API services (such as Blowfish and others) to check the possible levels of “severity” that that a transaction can bring to the user (a risk score). This goes from full block screen for possible malicious transactions (or message signing) to warnings of the different levels of caution the user should have before signing or confirming a transaction.
Other measures include:
Address validation to make sure you don’t send to a wrong address
Addresses that are always visible in their entirety to make sure the user is not targeted to specific attacks surrounding address composition
Network validation and warnings to make sure the user does not send to the wrong network
Fee sanity checks to make sure the user doesn’t overpay for a transaction
Networking privacy
To protect users’ privacy and personal data in a way where this data is not leaked on network requests – especially to third-party services – we’ve developed an API gateway to proxy requests. This proxy allows us to not pass user requests to third-party services and does not not reveal a client’s IP to external or public providers.
This backend service is basically an API for querying public blockchain data. Within the wallet security architecture, its purpose is to encapsulate this functionality behind a common API across all blockchains so that Kraken Wallet does not have to implement blockchain-specific behaviors for data querying.
This backend service defines this common API. It ultimately proxies requests to other parties from which it fetches the actual data. It does not index blockchains itself nor does it maintain state.
Security assumptions
Our security architecture operates on a few key assumptions for optimal protection. We presume:
The user’s device is not rooted, nor is the OS outdated and susceptible to critical vulnerabilities which could grant an attacker access to device memory
The Keychain or Keystore package provides strong enough protection
The mobile OS offers solid sandboxing between apps’ processes, ensuring that memory containing sensitive data like seeds is managed properly
Additional functionality
The app operates on the principle of only storing the minimum data it needs in order to run the wallet
No third-party analytics or crash reporting software development kits (SDKs) are used on the client
With our efforts to not leak any data to third parties, it wouldn’t make sense to include extra data tracking – which means you won’t find any analytics or crash report software in the client
No over-the-air updates (outside of the regular AppStore/Play Store updating flow) are allowed or implemented on the codebase
The user can expect a compiled piece of software that can’t be updated without their opt-in consent
Tokens list and reputation system
In order to help users to manage their tokens, we implemented a list and reputation system based on the assets provided by Kraken and other third parties
NFTs spam
An initial effort that we plan to keep improving upon is spam and spam-related attack detection, where spam is automatically archived in the user’s folder
External security audit
The security of our self-custody wallet was rigorously evaluated through an audit conducted by Trail of Bits, a well-regarded security auditing firm in the industry. This audit encompassed a detailed examination of our codebase and client architecture, aimed at identifying and addressing potential security vulnerabilities.
To ensure transparency and provide insight into the security of our platform, the results of this audit are publicly available. This open access allows users and interested parties to review the findings of the security analysis conducted by Trail of Bits. The report serves as an important resource in understanding the security measures we have in place and our commitment to maintaining a secure environment for our users.
Prioritizing security, transparency and user control
Kraken Wallet strikes a delicate balance between convenience and robust protection in the face of inherent platform constraints. Our approach has always been to begin with an interoperable wallet structure that is widely recognized. This solid foundation sets the stage for us to innovate and add new capabilities, with the goal of offering our users an ever-evolving, top-tier security solution for self custodying their crypto assets.
These materials are for general information purposes only and are not investment advice or a recommendation or solicitation to buy, sell, stake or hold any cryptoasset or to engage in any specific trading strategy. Kraken does not and will not work to increase or decrease the price of any particular cryptoasset it makes available. Some crypto products and markets are unregulated, and you may not be protected by government compensation and/or regulatory protection schemes. The unpredictable nature of the cryptoasset markets can lead to loss of funds. Tax may be payable on any return and/or on any increase in the value of your cryptoassets and you should seek independent advice on your taxation position. Geographic restrictions may apply.