Authenticate data before decryption with GCM and OpenSSL - encryption

I'm using AES-GCM to decrypt some data. I have some additional authenticated data (AAD), the authentication tag and the actual encrypted data.
What I need to be able to do is authenticate the AAD and encrypted data before actually decrypting it.
I know that OpenSSL's EVP_DecryptFinal_ex function will return 0 if the data fails authentication, but there doesn't appear to be a way to verify the data without actually decrypting it.
The reason I need to do this is that my encrypted data could be quite large, so I'd like to only decrypt it pieces at a time using EVP_DecryptUpdate. However, doing this would provide with with data I can't be sure is authentic.
What I need to be able to do is authenticate all of the AAD and encrypted data, and then use EVP_DecryptUpdate to decrypt it parts at a time. I could decrypt all the data at once to authenticate it, although this would add additional computing time to my application which I want to avoid.

Related

Saving decryptable password

I know there was question like this million times, but I was unable to find answer that will fit my needs.
I'm building something like small internal password manager for my company, to store login data for various servers and so on.
When new user is registered, his password will be saved in database in salted/hashed version so no one can get access to it (and for that part I think it's all ok, correct me if I'm wrong).
But then, when user is logged in, he is able to add new server with it's login details.
Question is, how to store those.
Because, at some point, I have to present this login details to user in plain text (that is whole point of this application).
Best I could came up with is using some kind of symmetric encryption.
Idea is that app will crypt login details with symmetric encryption and save it in that way into database, and then when data is needed once again will extract data from database, decrypt it with same key and present to user (and key should be in source code of application?).
It could be asymmetric encryption but it's the same if public and private key are stored in same source code, then there is no any benefit of using it?
That doesn't seem too secure, but I can't think of anything better.
Is there any better way to do this, to store this login data?
If it's important to you, application will be in PHP and database is Oracle
I would just use symmetric encryption. The standard steps are:
Derive a symmetric key from a user-supplied password (e.g. PBKDF2 or scrypt)
Encrypt the data using AES-128-CBC or better with a good random IV
HMAC the result (e.g. HMAC_SHA256) or just use AES GCM mode
Store IV+ciphertext+MAC in the database.
This can all run in a browser these days (see crypto-js and aes-js). That way the server never gets to see the plaintext password (not sure if this is a requirement).
The MAC can also serve as a password hash, i.e. if the MAC validation fails, then it means the supplied password is incorrect.

How to save Two Factor Auth TOTP Secret?

I'm currently developing two factor authentication based on totp. For this you have to generate a secret and save it on the server side and on the client-side (usually through the QR code).
My Question: How do I store it in the database? My requirements are that it's saved secure, preferably encrypted. Hashed doesn't work because I need to be able to have the plain-text value in order to calculate the totp secret code. When I encrypt it, with what key? Should I use a general key? Should I use the password from the user as the key? This would have the disadvantage that when a password reset is done, I can't Decrypt the totp secret key anymore.
Any ideas?

How or What is the best way to pass an encryption key?

Ok. so, encrypted data is sent from the computer to the server and spread to other computers. And, let say there is a person in the middle attack?
Here is where I'm confuse; The client/server need to decrypt the data with the key, but if the key can be seen by the client computer then the attacker can see it in the data as well. The key can be encrypted, but another key would have to be sent un-encrypted. so how do you pass the "key" to decrypt the data?
So when I hear new chat system saying they are enprypted their client messages; I'm wondering, how are they doing it? When hacker can try to find the key in thier data and decrypt the message.

How should I store usernames/password for automated authentication?

An organization I work for has a few different websites they use on a daily basis. I've been asked to develop a web application (using ASP.NET) that can access/synthesize information from these and display it in one location. Unfortunately, one of the websites does not support OAuth or anything similar, so I need to store their login credentials in a database.
My first thought was to use their credentials for my site as a key to encrypt their credentials for the remote site. For example: Bob logs in to my website with the password hunter2. Using that password, I decrypt Bob's credentials for www.example.com and log in as Bob there. Since I don't need to access example.com unless Bob is on my site, I can discard the decrypted credentials once he's done.
My assumption that simply using hunter2 (or whatever Bob's password is) isn't enough and that there is a "standard" way that I haven't been able to find on Google or Stack Overflow.
If you can't avoid storing the passwords on the server, then encrypting with the user's "master" password (e.g. "hunter2") is your best bet. No other approach offers protection in the event that the server is compromised. Now... how much protection you get hinges entirely on the complexity of the user's master password. I'll offer my analysis of the security of this scheme at the end, but before that, let me review the pitfalls to avoid.
First—and I assume that you already know this, but—you must not store the user's master password anywhere. Ok, with assumptions out of the way...
Do not use the user's actual password as the key to the encryption function.
Consider what would be possible if you did: what if an attacker managed to download your entire users table, complete with encrypted example.com passwords? We all know that user chosen passwords are easy to guess. What would stop the attacker from repeatedly decrypting the encrypted example.com password, trying 40 million commonly used passwords as the key, discarding any result that doesn't look like a password (that is, the decrypted result does not appear in the wordlist)? AES is designed to be fast. While not an apples to apples comparison, a sense of the speed of AES should be imparted when you consider that an encrypted version of the aforementioned 500mb wordlist could be decrypted in about one second on modern hardware. Worse yet, the attacker would not only get the example.com password, they would also have the key used for encryption, or in other words, the user's master password!
That, in a nutshell, is why you need to use a key derivation function (KDF). A KDF will ideally protect you in three ways:
Require a non-trivial amount of time to compute each key. A user can wait one second for the server to turn their password into a key. An attacker may be less inclined to wait 40,000,000 seconds—see analysis below.
Salt the password. Without salt, an attacker could brute-force the entire users table in one pass, not to mention make a space-time tradeoff.
Prevent recovery of the master password, even if the attacker recovers the encryption key.
One such KDF that provides all three is PBKDF2. Conveniently, there is an implementation built in to .NET:
public static byte[] DeriveKey(int keyBitSize, string password, byte[] salt) {
const int iterations = 1<<12; // Once set, any change will break decryption.
using (var kdf = new Rfc2898DeriveBytes(password, salt, iterations)) {
return kdf.GetBytes(keyBitSize);
}
}
Analysis
40 million seconds is less than 500 days. Since wordlists are usually ordered with the most commonly used passwords first, the attacker has a good chance of finding the password in significantly less than half the time it takes to try the entire wordlist. As a final wrinkle, it is possible to try keys in parallel: a 500-node botnet could try the entire wordlist in a day.
That's the problem with relying on the user's password for encryption security. You can choose to accept this risk or you can decide not to store the user's password on the server. If you decide to store encrypted passwords on the server, you can mitigate the risk by increasing the complexity requirements for the user's master password.
Whatever approach you take will have issues that will leave you doubting yourself. You need to balance the solutions against your environment & see what best fits.
Will each user of your app have an account on the remote system? How are users authenticated by your system? Will your app run in a trusted environment (eg corporate network).
I wrote a similar app to front an internal system that had it's own username & passwords. My app used Windows Integrated auth to figure out who the user was. it then asked for their password to the remote system & encrypted that value using a hard-coded key & stored the value in the DB. It could then retrieve the value, decrypt it & supply it to the remote system when needed.
Now in a non-trusted environment, someone could obtain my binaries & work out what they key was & get all the passwords. That would be bad. But on a corporate network, if they did that, they should come & work for me.
You already have access to the user's clear-text secondary passwords, so regardless of whether or not you throw away the encryption key, you're still responsible for their safety when it is in the clear. Keep that in mind when you handle the passwords.
If you use the user's own password to encrypt, you are reducing the strength of all their secondary passwords to the strength of the primary one. This is probably bad since a) user passwords are notoriously weak already (I know, why do we even bother in the first place?) and b) even with the strongest of passwords, it still won't match the strength of a solidly random 256 bit AES key.
My suggestion is to consider having a single AES key that encrypts their clear-text secondary passwords. Then, guard the AES key well. It may make sense, instead to have a root AES key that encrypts many sub-keys, one for each user. You'll have to do a risk analysis, I suppose.

What's the best way to save user login and password in flex?

What's the best way to save user credentials in flex? Local storage doesn't seem like good place for storing confidential data, because it saves information as a plain text.
You shouldn't. Use browser cookies or a session token to identify the user to the server. For instance:
User enters username and password into a form in Flex and clicks login.
Server validates credentials. Then either in memory or in a database the server associates a random (and sufficiently secure) token with the user. Then the server returns the token to the client.
Client saves the token in either a cookie, LocalSharedObject, or just in memory. Then subsequent requests also include the token.
You can use ExternalInterface to communicate with JavaScript and store data in browser cookies.
Don't store users' name or password in cookies - create a session in the server with credentials in it, and store the session id in the browser cookies.
if your service don't support credential, then the only think you can do is save user login state in SharedObject.
You can save hash value of UserName + Random Token to SharedObject and save a copy of UserName too in SharedObject, then when application created creationComplete check wheather the hash value match with the saved user name.
the good thing about this trick is:
Password never persisted locally.
Harder to fake login because need to
match username with the hash value.
a bit hard to explain here you can check it here, source code is available for download.
User credentials are normally stored in a session variable.
You don't necessarily need to save the credentials as plain text in Local Storage; in fact, Local Storage (SharedObject) is actually serialized as AMF, so it's not plain text to begin with. Whatever medium you use to store your sensitive data, you should certainly consider using some sort of hashing or encryption techniques like SHA1 or RSA.
The difference between hashing and encryption is this:
Hashing (SHA1, MD5, etc) is a one-way encryption - in other words, it's very difficult to determine the original value of the hashed value, so what you can do is compare one hashed value to another since these hashing algorithms will always spit out the same thing.
Encryption (RSA, AES, etc) is a two-way encryption - in other words, you can determine the original value of the encrypted data, usually by using a public/private key combination
It really depends on what you're trying to do.
Hope you come right
SharedObject is a very bad place to store your password in.
Please see this:
http://livedocs.adobe.com/flex/3/html/help.html?content=security2_22.html

Resources