Securely storing encryption key in WinRT / Windows Store apps - xaml

I would like to encrypt some of my Windows 8 app data (stored in local storage folder). This is not very sensitive data, however I would like to prevent users from forging/modifying it (and was looking into encryption as a way to achieve that).
Is there any secure key store available that I could use to save my key for later reuse? What I would like to do is:
1) on the first run generate the key and store it somewhere,
2) encrypt the data using the key,
3) anytime i need to decrypt the data i would retrieve the key from the store.

Did you have a look at the PasswordVault class yet? http://msdn.microsoft.com/en-us/library/windows/apps/windows.security.credentials.passwordvault.aspx
Basically all confidential information should go in there.
If you want to 'prevent users from forging/modifying it', the question is, how much energy you are willing to put into this.
Generally speaking, data in the PasswordVault should be secure without using additional encryption. Regarding security above that level it can be said that an attacker with physical access to the computer can do anything with it, as you'd have to store the keys on the same machine. Anything more swiftly reaches a point of diminishing returns against invested effort - i.e. just adding some obscurity instead of real security.

Be careful with the PasswordVault solution, I discovered that it is actually a problem because it is a roaming settings. If you open your application on two devices at the same time, you will get two encryptions keys, but after a day or so, the roaming setting will override the first generated encryption key.

Related

Any local privacy-oriented user authentication for mobile apps?

I'm building an app and I'm being very cautious about the user privacy on the app. I do not want to collect any data. Not even email IDs. Is there any way to do user authentication without email/phone number?
One idea for now is using biometrics on the phone itself. FaceID/TouchID etc. But that brings up challenges wrt syncing their data in case the user wants to use from a different phone. Any workarounds?
You can safely collect as much data as you like inside the app, so long as it stays there.
The problem is that you want to reliably identify a user account (though not any specific user data) without letting any of that data out. It's become quite common to use hashes (usually SHA256) of email addresses as identifiers, however, if everyone uses the same approach it's like a distributed rainbow table. You can however deploy the usual defence against such attacks by salting your hashes so that they are unique to your service.
If you encrypt the user's data on-device using a key that only they know, and only ever transmit and store encrypted data (i.e. to which you have no access), then they would be able to use the same local identifiers and their key to read the data from a different device. Because data is only ever encrypted and decrypted with the same key you can use symmetric encryption - look at using libsodium to do this.
You might want to consider some kind of 2FA to go with this as otherwise intercepting this identifier could allow unauthorised access.
Depending on the sensitivity of the traffic, you may want to try to hide meta-information such as connection dates, times, and volumes, so you could get the app to generate random data to hide the real data within.
Disclaimer - I Am Not A Cryptographer! I recommend you ask for more qualified responses on https://security.stackexchange.com.

How do I store an encryption/decryption key in VB.Net?

Let's say I have a program written in VB.Net with encryption code that relies on a key being set to encrypt and decrypt. How do I securely store the key in the program? If it's plain text in the code, it could be reverse engineered. If it's a setting, then it is stored as plain text in the x.exe.config file and even easier to find.
Can the x.exe.config file be set to encypt? If not, what's the safest way of hard coding the key into the program?
The method I've used is encrypted using a different method, then encode that (as it's non-ascii text) and store that in the settings, but that in turn could be decoded if the program is reverse engineered.
What do other people do in this situation?
You've set to an impossible task. The problem is that by hardcoding the key into the program, as you've noted, the user can still get the key by reverse engineering. If you put it in a file somewhere, the program needs to be able to read it, and therefore the user can also access it in the same way.
The fundamental problem you have is that the software needs to access the key, and for that, the key must be stored somewhere it's reachable by the user too. It can be within the binary or in the computer, but the binary can be analyzed and the file system can be inspected. Encrypting a file protects the key, but just recreates the problem with the new key.
This is also the very same problem that all DRM schemes face. They give users access to the the full software but want to limit it in some ways, but the user has everything in his computer to run the software. That's why it's always possible to pirate every desktop software, if enough effort is put towards it. You only can make it more difficult by obfuscating the key.
But what can you do then?
An alternative approach is to not have the user to have the DB credentials at all. Or make them useless for anything significant. I can think of two approaches here:
Have the system communicate with a webservice and never to the DB directly. This way, the user only knows the address of the server and the WS can request any authentication as needed, before going to the DB. The WS is then the only one to ever touch the DB. This is what all websites do in practice, the visitor doesn't ever sees the DB, but interacts with it though the web server.
Another option would be to give the user direct DB access, but those credentials only give permission to call some stored procedures (or access views without sensitive data) and those in turn request some sort of authentication before proceeding. This way the DB credential becomes not that sensitive as long as its permissions are kept to the bare minimum and privileged actions are properly validated before proceeding.

Cryptographic Agility and Key Management

I have a design question. I have a web application that uses .NET encryption APIs to encrypt/decrypt data. (App uses old crypto algorithms like MD5 and SHA-1). Also, app hard-codes the encryption keys in the production code.
I would like to;
1 ) Update existing old algorithms (MD5 and SHA-1) to new ones.
2 ) Move encryption keys from source code to a secure share.
3 ) Can change the encryption keys easily and regularly
My Design;
Algorithm Update
For the algorithm update, we use specific .NET implementations of crypto algorithms. We use classes like MD5CryptoProvider or RijndaelManaged. These are all hard-coded. I am going to remove the specific algorithm dependency and make it more agile like;
HashAlgorithm algo = HashAlgorithm.Create(MyPreferredHash.ToString());
algo.ComputeHash(...);
MyPreferredHash value will be loaded from a config file so that we can change this when we want to.
Question: Upgrading the code is easy to do this. However do you see any potential issues with changing crypto algorithms? We do not store any encrypted or hash data anywhere and web application is stateless. All the hash values are generated and appended to url strings and decrypted from another pages. Therefore, no data is stored. Except the cookies. When we encrypt cookie and send it back to user, we decrypt it when server receives it. In this case, i thought of destroying the cookie and send a new one to the client. Is this reasonable? Any other issues you think of ?
Key Management
Second part of the design, is to remove hard-coded keys from source code to secure share. After this, I need to be able to rollout new encryption keys. Each encryption key will be associated with a expire date. When we rollout a new encryption key, new key will be used for encryption and decryption. If it fails to decrypt, then we can try old keys. Old keys will be used for decryption or verification until their expire date. When they pass their expire date, they should retire.
For the storage; I am thinking of storing the encryption keys in a config file in the local machine as "encrypted" by a master key which will reside in a secure share. Therefore, anybody who doesn't have access to this secure share will not be able to see the master key. Master key will be loaded from secure share to machine registry when a machine reboots. The encryption keys in the local machine will be loaded from config file (local) and decrypted by master key in registry.
This storage choice will give us storing only one master key in a secure share and also historical changes to the encryption keys as we will store them in version control system.
The challenging part is the key change/update.
What is the recommended key change algorithm here for a distributed web application? If we are doing partial deployment after a release, not all the machines will have the same config file content (e.g. new encryption key added). All site deployment can take 1-2 weeks. This is also another concern that if we should wait for all deployments complete so that these keys will be active after that.
Any other feedback?
You are quite right to design your app to be agile in the face of unknown future attacks on particular encryption algorithms.
The simplest way to future-proof your app in a robust way would seem to be to switch to using a standard data format for your encrypted information, and use a standard library to do the hard lifting. The choice of a specific standard to use would depend on what kind of data formats you're working with, but there are good candidates to choose from. Then when there is a future attack, you can just change some parameters, or update to the latest version of the implementation.
Doing crypto is very tricky. Best to leave it up to the experts.

Correct and secure manner of storing in-app-purchases

What is the best way to store an in-app-purchase on a device,
so that the purchases can also be accessed offline but
the security of the purchases are not compromised?
Do not store anything valuable on the device as it cannot be trusted and it can easily be compromised by someone motivated.
Now, all of this depends on the type and value of the item that is being purchased and what happens if its compromised.
If its truly valuable then use a remote secure server for managing secure items. In app purchases include a receipt that can be verified by your remote secure server talking to apple's servers directly through a secure connection. See this link to verifying store receipts.
As far as I know, the most convenient way to securely store a purchased asset would be to use some form of encryption.
The user should be able to download an encrypted asset, and the app should decrypt it on the fly.
However, make sure that you store the key in a secure fashion as well, as string keys (within the app binary) can easily be recovered by a skilled hacker. A good way to secure the key would be to use some sort of authentication with a server-based system. The app would get the key off the server and keep it only for the few moments required to decrypt the asset.
This defense mechanism is not impregnable; I feel that it is sophicaticated enough to discourage most users from attempting to undermine it.
To decrypt your assets on the device, a good idea would be to use CommonCrypto. It's provided by Apple (with the iOS SDK), so you don't have to build it from scratch and you don't have to provide documentation (required by US law) for your app. I find Jim Dovey's Common Crypto wrapper the easiest way to use it.
Hope that helps. :)
You'll want to encrypt the file, for which your best bet is probably Common Crypto. In order to be able to access the data offline, you need to store the encryption key on the device.
The solution is to use the keychain: Use SecRandomCopyBytes to generate a key of sufficient length, and store it in the keychain using SecItemAdd. Then use that key to encrypt the data and write it to the device's local storage in the normal manner. When it comes time to read the file back from disk, use SecItemCopyMatching to load the key from the keychain and use it to decrypt the data.

saving key in application settings

i am starting to use cryptostream class. i may be wrong, if you encrypt something, close the app, and then try to decrypt it, it will not be able to because a different key will be generated. because i do need this functionality, i am wondering if it's possible to save the key in application settings and whether this is the right way to go?
If you always run your app under the same user account (it can be a local user or a domain user), the best option would be to use DPAPI. The advantage of using DPAPI is that you do not have to worry about the key (the system generates it for you). If you run the app under different user identities, then it gets more complex because the options that are available range from bad to worse (the major problem is: how do you protect your secret: key, password, passphrase, etc). Depending on what you want to do, you may not need to use encryption at all (e.g. if you want to encrypt a connection string, consider using integrated windows authentication, which does not require a password). For more info on the topic, check out this MSDN article: Safeguard Database Connection Strings and Other Sensitive Settings in Your Code; it may give you some ideas.
Lots of applications save the keys in configuration files. It's a common bad practice.
It's not secure but all secure options are hard to implement. There are options using different factors,
You can derive the key from a password using PBE (password-based encryption). But you have to enter a password to start your application. This is so called "What you know" factor.
Put the key in a smartcard. This is very secure but you need to have access to the card on the machine. This is called "What you have".
Ignore other schemes involving encrypting keys with yet another key. It doesn't really change the security strength.