I'm going to rephrase a question I asked earlier, as I don't think anyone understood what I meant.
Basically, I'm writing a web based password locker, which can handle multiple accounts; users can share passwords (useful if you're in a website company and need to share login details to, for example, 1&1 or Fasthosts).
I've been doing tons of research into encryption algorithms, CSPRNGs, hashing algorithms, and key stretching. I don't want to implement my own encryption or hashing algorithms. Instead, I want to use existing algorithms and apply them in a way that I've understood from my research.
I'm not a cryptographer, so I may have misunderstood something, or something I've read about has actually been found to be insecure, or it was an old way of doing things that something better replaced. I'd like to discuss what the thoughts are about implementing hashing for storing the passwords of user accounts and encryption for storing the login details of websites that users can share.
First of all, I need to store hashes of account passwords (these are the accounts that log into the application to view the shared passwords).
After reading around, my understanding is that to make a hash "more secure", you need to use scrypt or bcrypt or pbkdv2. I've found an implementation of these 3 algorithms in CryptSharp. (Hopefully, this is a secure implementation of these algorithms.) After further research, it looks like sCrypt is a more secure way of creating a hash.
Is scrypt a secure way to create a hash of a user's password, or should I use one of the other two? (Maybe sCrypt hasn't been tried and tested as much as the other two.) How can I tell if the implementation of sCrypt in CryptSharp is a good secure implementation?
As the data will be shared between users, I shall need to make sure that the system uses a master encryption key for the entire project, and that this is stored securely.
My thinking here is generating an encryption key and initialization vector (3 of them; I'll explain why). These will be generated with RNGCryptoServiceProvider, and they will be concatenated into Key1|IV1|Key2|IV2|Key3|IV3 so that they can be split and used with the encryption algorithms.
I need some way of storing this concatenated string of IVs and Keys. After some research, I came across Microsoft's Data Protection API (
ProtectedMemory.Protect(secret, MemoryProtectionScope.SameLogon)). My understanding with this is that the App Pool will need to run under a user account, and "load profile" set to true. The resulting encrypted string will then be stored in an XML setting file.
With regards to encrypting the passwords to be shared, I read about cascading encryption (used in TrueCrypt). The encryption algorithms TrueCrypt uses are; AES, TwoFish, and Serpent. I've found an implementation of these which, again, I hope is a secure implementation. This is where the 3 IVs and Keys will be used; so effectively the data will be encrypted like
Serpent(TwoFish(AES(data, key1), key2), key3).
Just to be clear, this is the process flow of encryption within the system:
- Upon installation of the system, the system will use RNGCryptoServiceProvider to create 3 encryption keys and 3 IVs.
- These 3 keys and IVs will be concatenated into a single string (Key1|IV1|Key2|IV2|Key3|IV3), so I can split them and use them in the 3 encryption algorithms.
- This string will then be encrypted using Data Protection API and stored in a settings file.
- All shared login detailsare encrypted using "cascading encryption" of
Serpent(TwoFish(AES(data, key1), key2), key3). The keys and IVs will be decrypted on-the-fly, instead of being stored in memory.
When it's time to decrypt the shared login details:
- The 3 keys and decrypted using DPAPI
- Encryption is reversed:
AES(TwoFish(Serpent(data, key3), key2), key1)
Is "cascading encryption" still a good idea? Is Data Protection API a good way to encrypt the keys and IVs?
So like I say, I know how to build the entire system and implement my understanding of hashing and encryption above into the system, but is what I've discussed the right way of doing things? Am I over-looking something? Did I misunderstand something? Am I using an old hat way of doing things?