Devise with previous encryption - ruby-on-rails

I'm currently developing a new application, I had made one in the past and I had done all the users manually but now I'm looking to use the best way possible to implement my users. I had thought in the past of using the gem but because of time reasons I didn't have the time to implement it, now that I'm starting fresh I wanted to start using the gem to optimize and use what the gem has to offer, since I really liked it.
Anyway, my issue is, for security reasons since I will be passing parameters through mobile I will be encrypting the password to pass it to my application, and then with that encrypted password I will encrypt it once again to compare it to the encrypted password, so what I wanted was a way to encrypt the password before devise encrypts it, that way when the mobile app passes the encrypted password it will match to the previous encryption.
I tried a before_save on the Model, without luck, it just saved the encrypted_password empty, I'm not sure why.
tl;dr I need to encrypt before the gem, tried to do it with before_save/before_create on the model but it didn't work, anyone knows any way to do it?

Consider the following fact: If you encrypt the password before sending it with a method which allows you to decrypt it at server level, then this means your method is not one-way and the password sent may be decrypted by other person using a middle-man attack. Then you are not safe at all.
It is much better to use HTTPS/SSL to send this kind of sensitive data. It encrypts all you send at transport level and does this in a way better than anything you can implement by yourself, no offense meant.

Related

What is the standard procedure used for login-systems in iOS-apps?

I am creating an app and a website for a project I've got going, but I'm not sure what I should do about login. This is not a "I'm a noob and I want an app with login"-question. I am somewhat experienced with both web-, database- and app-development, but I've never actually touched the subject of security before other than by application templates.
What I'm imagining is a 'simple' login-system like Skype, Facebook, NetFlix, really any app that you are able to log in to, which also has a website to log in to.
A part of my question is towards the security of the process. My initial thought is that a password in clean text should never be sent over internet, which makes me believe that the passwords should be hashed/encrypted on the phone, as well on the website, when logging in. I've done some small-time hashing/encrypting before, but just by using sha1 and md5 to "convert" the text. What's the proper way to do this? With my current knowledge, I assume that if I'm using md5 to encrypt a password, anyone could decrypt it with md5 too, but that I could use a SALT(?) or some form for altering key. Is that how the "big boys" are doing it, or is there a secret passage I don't know of?
Now onto the real question.. How should I store a login securely?
What I've tried: When making a "test-project" in Xcode for this, I simply created a class User with a field for username. When "logging in" by entering a username and password, I simply sent a POST-method HTTP-request to my .php-page, which simply performed a SELECT * FROM User WHERE Username = '$_POST['username']' AND Password = '$_POST['password']'; If the database returned one row, then the password was correct, and the page could print out the user in JSON or whatever. When the device got the successful login, I converted the user-object in the app, now containing the username (and potentially UserID, E-mail, Address etc.) to NSData*, and using NSKeyedArchiver and NSKeyedUnarchiver to save and load the user, never to authenticate again. If the user clicks "Log out", I wipe this 'archive'. This works, but I sense that it's not a particularly secure way of doing it. If so, why exactly is that?
(Our back-end is currently Google's App Engine(java), which has support for OAuth. Some are recommending this, but we can't find any proper documentation that makes sense for our plan with custom users)
Password Transmission
The easy way to secure this is to just send passwords over SSL. If you set up an SSL certificate and do all your authentication over https, all the back-and-forth communication is encrypted by the transport layer. Note - md5 is not an encryption algorithm, it's a weak hashing algorithm - don't use it for security.
Storing Logins
Your passwords should be stored in the database as a salted hash (random salt, with a collision-resistant hash function such as SHA256). Don't store the plaintext version of the password anywhere. If you're using PHP on the server side, you can use the new password_hash() function or crypt() to generate and compare your salted hashes.
If you're communicating securely over SSL, you should be able to just use the session capabilities of your web server to keep track of logins (e.g., $_SESSION['user_id'] = ...).
If you want to securely store your username/email/address, or anything else for that matter, the built-in keychain is the only Apple-happy way to go.
Have a look at SSKeychain (or PDKeychain or UICKeychain) and extend it to include each property you'd like to store. Generally it's used to store username and password combinations, but can be extended to store arbitrary data safely.
As for passing secure data to your server, do it over HTTPS.
I can provide examples if you'd like.
Another option is to add some sort of OAuth or XAuth login process.
That way, you are not storing any passwords, but only so called "Tokens". The tokens expire, and can be revoked.
Not storing the username and password at all is the best way to secure them.
Alex

iOS: Encrypt Login Password to send to API

I need to encrypt an NSString before sending to a WebAPI.
What are the best practices for this? I've been looking at different articles but haven't found what I'm looking for.
The whole hash/salt with date thing seems like the best approach as of this writing.
ANyone know how to do this in iOS?
Then, do I just store it in the DB as varchar(50)?
And for subsequent logins just do a text compare?
Thanks all.
Encrypt and authenticate the connection to the server with HTTPS. This counteracts eavesdropping and MITM attacks. Be sure to verify server certificates on the client side.
On the server, hash the password with a randomly generated salt.
Store the hash and the salt in a database. Yes, you can use something like a text or varchar(50) to store the hash and salt.
This has been covered in a few other questions before: see Best way to store password in database

Encrypting (not hashing) and storing user passwords on a rails server, using devise cookies

Got a bit of an issue where I am required to maintain a secure connection with one server that proxies out requests to another, over basic authentication. However I can't be allowed to gain access to the password for the users who want to access the other server. Can anyone suggest a way to store the password (having been given it once) securely in say the session variable, encrypted by a key that only the client holds until the point when it's needed?
After a time it can expire, ie, you could give the username and password and half an hour would be an acceptable time to keep the credentials in case the user wanted to access the site again.
I've rewritten this a few times after producing pure waffle, sincerely sorry if the editing didn't make much difference.
If your server is going to be handling the password in plaintext (to talk to the other server with Basic auth), you're going to gain access to the password. Perhaps you want to avoid storing the password in plaintext?
Send the password in plain text to the server, which then encrypts it, stores the encrypted version and adds a cookie to the client with the key. Then any future requests provide the key to the server.
If you're looking for an encryption library, Recommended two-way encryption gems for Ruby?

How should I store passwords locally for a multi-user application?

I want to create a multi-user application, but I don't know how to save and read encrypted passwords.
procedure SavePass(Password: WideString);
var
Pass: TIniFile;
begin
Pass := TIniFile.Create(ChangeFileExt(Application.ExeName, '.PASS'));
Pass.WriteString('Users', 'USERNAME', Password);
Pass.Free;
The passwords must be stored on the computer.
This works but it's stupid to save passwords using this.
Hashing passwords would be also good.
If the connecting software accepts hashed passwords, it's not going to stop people who steal the hashed passwords from connecting. All it will do is hide what the real password is.
Furthermore, if the software that you're connecting to does not accept hashed passwords (database, website, ...), you're going to have to store your password in such a way that you can get it back to its original state. A hashed version is not going to help you there.
If you want to scramble your storage so that humans cannot read the file, you could use Windows.EncryptFile() and Windows.DecryptFile(). In newer Delphi's that's neatly wrapped into IoUtils.TFile.Encrypt() and IoUtils.TFile.Decrypt.
If you really want to stop others from reading the cleartext version of your password, you're going to have to use some encryption with a key. Where do you store that key then?That would defeat the whole purpose of storing a password in the first place. It's better to prevent access by other users by using user privileges to the file system for example, because anything you or your software can do, a "hacker" can do if he has the same privileges.
My suggestion is to not use passwords in your application at all, unless you really need to. The user experience of having yet another password to enter & remember is usually not needed.
What I do for my applications is default to using the domain and user name of the current user as the identification. The user has already logged on with a password, or more secure system if they want it. Only by logging on can they be that current user. My server then accepts that as their identification.
Variations on this include optionally passing the machine name too, so that the same user is treated differently on different computers (when they need to use more than once computer at once). And of course you can still allow a normal password if you want to.
You should store hashed passwords. For example you could use one of the SHA algorithms from the Delphi Cryptography Package. When you check passwords hash the password that the user supplies and compare against that saved in the file.
Have you considered using Windows security rather than attempting to roll your own?
As an aside, you are liable to encounter problems writing to your program directory if your program resides under the program files directory and UAC is in use.
There are hash and encryption routines in Lockbox. You should hash the password concatenated with a random 'salt' and store the salt and hash together. To make it harder for people to brute-force the hash - trying all likely passwords until the right one is found - you should iterate the hash. When the user subsequently enters their password to login take the salt from your store and hash it with their entered password, and iterate, and test the result against the hash you have stored. If they are the same they have given the correct password.
As long as you can, don't store password, but hash them properly (use a salt, repeat hash n times, etc.) because rainbow table attacks are feasible and work well against poor chosen passwords and too simple hashing.
If possible, take advantage of "integrated security". Use Windows authentication to avoid storing passwords.
If you really need to store a master password or the like, use Windows APIs like CryptProtectData to protect them locally.
I think its best to keep user-specific settings in the Registry under HKEY_CURRENT_USER. That will keep their settings all together and separate from other users' settings.
You'll automatically read the correct user's settings when you read from this area of the Registry, and you should store your password there as well. Yes, do encrypt it as David recommends. The Registry is easy for anyone to read using RegEdit.
Here's an article on how you can write to and read from the registry.

Rails database - how to store encrypted data using the user's password?

I have a database that will be holding sensitive data, so it should be encrypted in the database. Basically the sensitive data are credentials to another web site. So I want to encrypt them with the users password + salt.
To decrypt the credentials one would need the password.
I see two ways:
On login, I could decrypt the credentials, and then store them in the session? Is that safe?
OR
Harder on the user would be to ask again for the password before decrypting the stored passwords/ids?
We don't want to have any ability to use the stored credentials ourselves.
I highly recommend "Security on Rails" for this. It's a tricky topic, so you'll need to spend some time reading up in order to get it right. They cover exactly this topic, including how to salt the encrypted data, unit test to make sure it is encrypted, and more.
Their sample code shows how to add class methods to ActiveRecord::Base so that you can make any database column encrypted in one line of code. Definitely an idiomatic Rails approach.
It's an awesome read - the unit tests blew me away, so seriously ... go get it.
By the way, when you said
We don't want to have any ability to
use the stored credentials ourselves.
you realize that because your code receives the unencrypted data from the user's browser, you do have access to the data in memory before it is encrypted on disk, or when it is unencrypted when the user wants to use that data later. And bad people could get access to that data if they root your box, sneak something into a Ruby eval(), etc.
Encrypting the data does help a lot, though. SQL injection attacks can't get the decrypted data, for example.

Resources