Flutter - Authenticate with a pin - flutter

I want to lock my app with a 6 digit pin. When the user creates a new pin the hash of this pin is saved in flutter secure storage. A pin is proofed by getting the hashed pin from the secure storage and comparing them. Would this be secure?
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:steel_crypt/steel_crypt.dart';
//Saves the hash of the pin in FlutterSecureStorage
Future<void> createPin(String pin) async {
const secureStorage = FlutterSecureStorage();
//Hash the pin and save the hash
var hasher = HashCrypt(algo: HashAlgo.Sha_256);
String hashedPin = hasher.hash(inp: pin);
await secureStorage.write(key: "hashedPin", value: hashedPin)
return;
}
//Check if the given pin is correct
Future<bool> checkPin(String pin) async {
const secureStorage = FlutterSecureStorage();
var hashedPin = await secureStorage.read(key: "hashedPin")
var hasher = HashCrypt(algo: HashAlgo.Sha_256);
return hasher.check(plain: pin, hashed: hashedPin);
}

Disclaimer: I am not a certified security expert, but based on what I do know about it, I'd say it's quite secure.
I did the exact same thing on another app of mine, and here is the reasoning/logic when determining that it was secure enough for my use case:
Flutter secure storage uses methods channels to Android's KeyStore and iOS's Keychain - those are operating system APIs provided by Apple & Google to us developers, and are made specifically for storing sensitive data.
When those APIs encrypt and decrypt values, only the operating system (not even our own apps) have access to the decryption keys and/or salts. Meaning no apps, not even our own could decrypt without the help of the operating system, who governs who should have access to decrypt something for a given app.
Like your approach, I was also storing the pin as a one way hash only (and not the actual pin, the truly sensitive data) and using flutter secure storage (hence OS provided encryption) also means that the data is encrypted at rest.
Future checks on pin input were also one way hashed, and compared to the securely stored value.
That said, it's all software running on an environment you don't control, so could it be hacked? Yes. But I'd trust the Apple and Googles data security engineer's abilities to harden against attacks far more than mine.

Well, the description of secure storage changes with consideration for
the platform.
If the platform is Android, then flutter_secure_storage stores data in
encryptedSharedPreference, which are shared preferences that encrypt
keys and values. It handles AES encryption to generate a secret key
encrypted with RSA and stored in KeyStore.
For the iOS platform, flutter_secure_storage uses the KeyChain which
is an iOS-specific secure storage used to store and access
cryptographic keys only in your app.
In the case of the web, flutter_secure_storage uses the Web
Cryptography (Web Crypto) API.
As wrote above, it depends, i trust on this package on my projects and never got any trouble, since it's made for it.
I strongly believe that the big Companies that use flutter make their own solution.
Of course you could do some research and develop your own encryption, but that will cost some time, if you want to study some alternatives to FlutterSecureStorage:
SQFlite with SQLCipher support
Sembast
Hive
Drift
Otherwise, i strongly recommend you to stick with this package.

Related

How to store and access encryption keys across Flutter apps

I have created a suite of two different Flutter apps that share a single firestore database.
The first app generates a QR code that would then be scanned and verified by a user of the second app. The QR code information is a string that contains some information I don't want users to see by simply scanning the QR code with their camera app.
I want to encrypt the string in the first app before encoding it into a QR code, and decrypt the string in the second app after the QR code has been scanned, but that means I would need to have the encryption key accessible in both apps.
Would I have to hardcode this key into the apps or transmit the key through the database? How can I achieve this in the most secure way possible?
You can use almost any mechanism you want to transmit the keys, but the one thing you shouldn't do is transmit it through the same database as where you store the encrypted data - as that would put that data at risk if the database is compromised.
So mail them, text them, write them on a piece of paper and mail it, or you can organize an in-person meeting/party where you exchange them (h/t to Little Brother). It doesn't really matter how, as long as it's a different mechanism than you used to store/exchange the actual data that is encrypted with those keys.
You can hard-code them in the apps too, but what the keeps anyone from downloading that app too and using it? Or is that precisely what you want, in which case 👍

SQLite Security in iOS

I am developing app, which uses sqllite db. I want to provide security to DB. Is there any ways to provide security to SQLite DB so that no one can read it by hacking device or something else.
Should we provide any encrytion or apple provides their own security? Which are ways to provide app DB security?
Thanks
#Quentin's comment is right - as long as someone has physical acces to your device, it's only a matter of time until it's cracked. However, you can make that amount of time take so long that it's not worth it.
If you were to encrypt your database, the decryption key would also have to be stored on the device (assuming you want it to work offline). You could use the keychain to store this key - then they have to crack the iPhone's keychain before they can get access to your data.
The other alternative is to only let your app work while online - store the key on your server and have the user login and authenticate before you pass the key back to the app. This s a bit more work from you but will ensure that the key and the data are stored in different locations.
Finally (and most securely), you could store everything on your server - that way you control the data nd the key yourself and deice theft won't make the slightest bit of difference. however, if your data set is big this might make the ui of your app more complicated. And it won't work offline, obviously :)

Application-specific data protection on iOS

I've seen some documentation and videos from WWDC about data protection in iOS5 and it seems very nice since it can encrypt all your application data and keep it protected as long as your device is locked. However, I see 2 main problems with that system-wide data protection mechanism:
1- if somebody manages to steal my iPhone while it is not locked (which is typically what happens on a "steal-and-run" case), it can potentially plug my iPhone into a laptop and access my data unencrypted
2- it forces me to define a system-wide passcode, which seems natural to some users but is still cumbersome to a lot of users. And it seems abusive that I force my users to define a system-level passcode even though my app is the only one where encryption might really require it. And it's even more abusive as a four-digit password is not such a good protection against brute force attacks.
So my question is the following. Is there any simple way to encrypt my data with a passcode specific to my application, so that every time a user launches the app, they have to enter the passcode, but they don't have to define one on the system level? If not, can I at least plug into standard data protection API's with such an application-specific passcode? If not, is it worth it to write my own encryption layer on top of core data to enable such a scenario? Or is it something that might be added to future versions of iOS (in which case I'll probably stick with system-wide passcodes for now and upgrade it later)?
Several data protection api's on other operating systems (e.g. DPAPI on windows) allow developers to provide supplemental entropy for the key derivation process used to protect the data . On those systems, you could easily derive that data from a pin number. Without that pin, then you can't generate the key and read the data.
I looked and couldn't find anything to this effect on iOS, but I am not an objective c programmer so frankly , reading apple's documentation is a pain for me, and I didn't look too hard.
Depending on your use case you may want to enable data protection in your app, but if the user doesn't use a passcode it won't give you much protection. I don't know if enabling that entitlement will force a passcode.
You could take the path to require that the app have a pin code at launch and then use that pin code along with some other data data to generate a key for the common crypto functions.
https://developer.apple.com/reference/security

Data protection on mobile devices

I'm storing some healthcare data on a mobile phone and I'd like to know what the best system of encryption is, to keep the data secure. It's basically a bunch of model objects, that I'm serializing and storing using NSKeyedArchiver / the equivalent on Blackberry (the name eludes me for now)
Any tips? I don't want to make up security protocols as I go along, but one of the other threads suggested the following approach.
Generate a public / private key pair
Store the public key
Encrypt the private key with a hash of the user's password.
Use the public key to encrypt the byte stream.
Decrypt the pvt key, keep it in memory, whenever the user logs in, and decrypt the stored data as needed.
Is there a more standard way of doing this?
Thanks,
Teja.
Edit: I appreciate it that you're trying to help me, but the things currently being discussed are business level discussions, on which I have no control of. So rephrasing my question, if you ignore that it's healthcare data, but some confidential data, say a password, how would you go about doing it?
There might be an easier way for secure data storage. With iOS 4.0 apple introduced system provided encryption of application documents. This means that the OS is responsible for doing all the encryption and decyryption in a fairly transparent way.
Applications that work with sensitive user data can now take advantage of the built-in encryption available on some devices to protect that data. When your application designates a particular file as protected, the system stores that file on-disk in an encrypted format. While the device is locked, the contents of the file are inaccessible to both your application and to any potential intruders. However, when the device is unlocked by the user, a decryption key is created to allow your application to access the file.
So only when your app is active, the files can be read back in unencrypted format. But the nice thing is that they are always encrypted on disk. So even if someone jailbreaks the device, or backs it up, the retrieved files are worthless.
This was probably introduced to conform to some specific data security standard that is required. I can't find that anywhere though.
For more info see the iOS 4.0 release notes.
http://en.wikipedia.org/wiki/HIPAA
Make sure you read and understand this!
edit: Sorry, didn't even bother to check to see where the OP is from, but even if they aren't from the USA there are still some good practices to follow in HIPAA.
HIPPA is a business practice and total system level privacy/security regulation. As such, an app can't comply by itself on random hardware for a random user. You need to determine how your app fits into a client health care provider's total regulatory compliance process before you can determine what algorithm might be found to comply with that process.
My best advice would be, don't store sensitive data in the user's mobile phone.
If that is not an option for you, then some kind of public/private key encryption, such as one you described, would be the next best option.

How can I encrypt CoreData contents on an iPhone

I have some information I'd like to store statically encrypted on an iPhone application. I'm new to iPhone development, some I'm not terribly familiar with CoreData and how it integrates with the views. I have the data as JSON, though I can easily put it into a SQLITE3 database or any other backing data format. I'll take whatever is easiest (a) to encrypt and (b) to integrate with the iPhone view layer.
The user will need to enter the password to decrypt the data each time the app is launched. The purpose of the encryption is to keep the data from being accessible if the user loses the phone.
For speed reasons, I would prefer to encrypt and decrypt the entire file at once rather than encrypting each individual field in each row of the database.
Note: this isn't the same idea as Question 929744, in which the purpose is to keep the user from messing with or seeing the data. The data should be perfectly transparent when in use.
Also note: I'm willing to use SQLCipher to store the data, but would prefer to use things that already exist on the iPhone/CoreData framework rather than go through the lengthy build/integration process involved.
You can encrypt individual properties in your Core Data model entities by making them transformable properties, then creating an NSValueTransformer subclass which will encrypt and decrypt the data for that property. While this is not the whole-database decryption that you're looking for, it will have a much lower memory footprint than decrypting an entire database into memory. Additionally, it will allow the decryption to be done lazily, rather than all up front, so your application will load much faster. Depending on the encryption used, I would even expect that the on-disk data accesses for loading each entity would be slower than the decryption process for the properties, so you won't see that much of a performance penalty when accessing the properties.
Transformable properties like this are very easy to use, because you read and write to them as normal, while the encryption / decryption goes on behind the scenes.
Do you need to encrypt?
Newer iPhones (3Gs, 4, iPad...) encrypt all data on the device. With a single, hashed, salted password on your app, no one can get to the data without a password. Data is sandboxed from all other apps.
Data Protection on iOS
"The purpose of the encryption is to keep the data from being accessible if the user loses the phone."
iOS has had Data Protection since iOS 4, and Core Data has supported this for a long time. Data protection is designed for exactly the kinds of scenarios you are interested in. By default, Core Data NSSQLiteStoreType files have NSFileProtectionCompleteUntilFirstUserAuthentication for applications built with the iOS 5 API or later. The WWDC 2012 session Protecting the User's Data goes into this topic in much more detail, and recommends using NSFileProtectionComplete. You can use this with Core Data by passing that value in the options dictionary used to open your Core Data NSSQLiteStoreType store.
Example:
NSDictionary *storeOptions = #{ NSPersistentStoreFileProtectionKey : NSFileProtectionComplete };
if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[self storeURL] options:storeOptions error:&error]){
The broader topic of device security is covered in iOS Device Security
I am currently using https://github.com/project-imas/encrypted-core-data to encrypt my coredata store. It is a custom implementation of NSIncrementalStore basically is a community replacement for apple's own persistent store that has an encryption option. It is a drop-in solution that works. You can also take the sqlite file out and decrypt it with whatever passcode you choose in many different clients.
The implementation does not have 100% coverage and doesn't allow for some features such as subquery predicates. I am due to submit my first PR to the repo to hope change that soon ;-). I almost have it completley working with a very complex coredata app. It also has the added benefit of allowing you direct SQLite access without having to worry about apple's implementation changing on you since you have full access to the source.
I succeeded in adapting Apple's CustomAtomicStoreSubclass example code for use in a Mac desktop application, resulting in an encrypted NSBinaryStore-style persistent store written as a single file in the filesystem. My approach:
Copy the CustomAtomicStoreSubclass & CustomAtomicStoreSubclassCacheNode class source code into my project and rename them
Store the key and initial vector in the Keychain
Use the OpenSSL library bundled with Mac OS X
Encrypt NSKeyedArchiver output and write the ciphertext to disc (decryption is the reverse)
I intercepted backing store reads & writes in the readFile, metadataForPersistentStoreWithURL:error:, setMetadata:forPersistentStoreWithURL:error:, and save: methods in CustomAtomicStoreSubclass.
The Subclassing Notes for the iPhone's NSAtomicStore Class Reference looks similar to that of Mac OS X's. Perhaps this approach might also work with the iPhone.
I know this is an old question, but it's still quite relevant and I recently had to tackle the subject myself.
Transformable properties are a potential solution, but did not seem to work with NSPredicates, which is a big drawback. I did not pursue the CustomAtomicStoreSubclass approach, but am curious if others have had success with it.
My concerns were similar to those of the original poster, and I ultimately wound up doing the following:
Decrypt the store to a temp file
Load the decrypted store normally
Migrate the store to an in-memory store
Delete the unencrypted store
In my case, my store was read-only, but this could be expanded to write the store back out, encrypt it, and delete the unencrypted store once more. You can also always skip #3 if you have a large store and/or aren't concerned about having an unencrypted file sitting around while your app is running.
The Core Data file I was working with was ~1MB, and could be encrypted/decrypted very quickly.
How do I encrypt or decrypt data?
"The Certificate, Key, and Trust Services API provides functions for generating symmetric and asymmetric encryption keys, creating and verifying digital signatures, and encrypting keys and nonces. The CommonCrypto library is used for symmetric encryption, hashing, and HMAC operations. Refer to Certificate, Key, and Trust Services Reference and the CC_crypto(3cc) man pages for for more information."
You can use Trasformables, and I confirm, you cannot use them with predicates, but (and it's worse) you cannot even use
... = [self primitiveValueForKey:#"crypted_data"];
if You use predicates..
it works fine if You crypt you data using:
[self setPrimitiveValue:cryptedPsw forKey:#"crypted_data"];
to crypt data. (and for example on the simulator.... and move on the project bundle later..)
Encryption is encryption no matter what format your data is in, and you certainly don't need to worry about how anything "integrates with the views." All you have to do is decrypt it before you try to read anything meaningful.