11---
22title : Security
3- order : 400
3+ order : 100
44---
55
66## Security
@@ -25,6 +25,80 @@ level of entropy, as this makes them hard to guess and hard to abuse.
2525** Always use HTTPS.**
2626
2727If your application allows users to connect _ their own_ API keys for a service, you should treat these keys with great
28- care. If you choose to store them anywhere (either in a [ File ] ( files ) or
28+ care. If you choose to store them anywhere (either in a file or
2929[ Database] ( databases ) ), make sure you store them
30- [ encrypted] ( ../the-basics/system#encryption-decryption ) and decrypt them only when needed.
30+ [ encrypted] ( ../the-basics/system#encryption-decryption ) and decrypt them only when needed.
31+
32+ ## Secure Storage
33+
34+ NativePHP provides access to your users' device's native Keystore/Keychain through the
35+ [ ` SecureStorage ` ] ( /docs/mobile/1/apis/secure-storage ) facade, which
36+ allow you to store small amounts of data in a secure way.
37+
38+ The device's secure storage encrypts and decrypts data on the fly and that means you can safely rely on it to store
39+ critical things like API tokens, keeping your users and your systems safe.
40+
41+ This data is only accessible by your app and is persisted beyond the lifetime of your app, so it will still be available
42+ the next time your app is open.
43+
44+ ### Why not use the Laravel ` Crypt ` facade?
45+
46+ By default, the ` Crypt ` facade - and by extension the ` encrypt ` and ` decrypt ` helper functions - all rely on the
47+ ` APP_KEY ` value set in your ` .env ` file.
48+
49+ We _ will_ use Laravel's underlying ` Encryption ` class, but you should avoid using these helpers directly.
50+
51+ In the context of distributed apps, the ` APP_KEY ` is shipped _ with_ your app and therefore isn't secure. Anyone who
52+ knows where to look for it will be able to find it. Then any data encrypted with it is no better off than if it was
53+ stored in plain text.
54+
55+ Also, it will be the same key for every user, and this presents a considerable risk.
56+
57+ What you really want is a ** unique key for each user** , and for that you really need to generate your encryption key
58+ once your app is installed on your user's device.
59+
60+ You could do this and update the ` .env ` file, but it would still be stored in a way that an attacker may be able to
61+ exploit.
62+
63+ A better approach is to generate a secure key the first time your app opens, place that key in Secure Storage, and
64+ then use that key to encrypt your other data before storage:
65+
66+ ``` php
67+ use Illuminate\Encryption\Encrypter;
68+ use Illuminate\Support\Facades\Storage;
69+ use Native\Mobile\Facades\SecureStorage;
70+
71+ function generateRandomKey()
72+ {
73+ return base64_encode(
74+ Encrypter::generateKey(config('app.cipher'))
75+ );
76+ }
77+
78+ $encryptionKey = SecureStorage::get('encryption_key');
79+
80+ if (! $encryptionKey) {
81+ SecureStorage::set('encryption_key', $encryptionKey = generateRandomKey());
82+ }
83+
84+ $mobileEncrypter = new Encrypter($encryptionKey);
85+
86+ $encryptedContents = $mobileEncrypter->encrypt(
87+ $request->file('super_private_file')
88+ );
89+
90+ Storage::put('my_secure_file.pdf', $encryptedContents);
91+ ```
92+
93+ And then decrypt it later:
94+
95+ ``` php
96+ $decryptedContents = $mobileEncrypter->decrypt(
97+ Storage::get('my_secure_file.pdf')
98+ );
99+ ```
100+
101+ ### Secure Storage vs Database/Files
102+
103+ Secure Storage is only meant for small amounts of text data, usually no more than a few KBs. If you need to store
104+ larger amounts of data or files, you should store this in a database or as a file.
0 commit comments