Ruby on Rails User Encryption - ruby-on-rails

I've completed several tutorials of different length and difficulty, a few of them building a custom authentication system from scratch. Most times I seem to find the following way of encrypting the password.
rails generate model User name:string email:string
and then
rails generate migration add_password_digest_to_users password_digest:string
Which produces a hashed password the the development database, when viewed, instead of the password (password1) it shows something like RFTER4dr3wxMnei instead.
Is it possible to add other attributes to the user via this method? For example, if I had two authentication methods (enter username and password) then (enter memorable information) could they both be encrypted using the same method?
or how, in theory, (and if possible) could you use it to encrypt all of the user's data (their name, email, date of birth, password etc)

This is not encryption, it is crystallographic hashing. A hash function is a function that produces a unique output for every input, from which it is impossible (theoretically) to reconstruct the input (short of a brute force attack, or something like a hash table).
Hash functions are perfect for authentication, because it means that you are not actually storing the password. You only store something the you can confirm the correctness of the password with. Every time someone logs in, the password given is hashed using the same algorithm, and the hashes are compared. This way, if someone breaks into your database, they can't actually get the passwords.
Information that you actually need to access, not just verify (you need to verify password, but access DoB, username, etc.) can be encrypted, but then you need to figure out how you are dealing with keys and such, because if someone can steal the encrypted information from the same place as the key, it's effectively pointless.
Worth mentioning: while it's great for learning, don't implement your own authentication systems in production unless you have too. Either use some open source code that has been reviewed by security experts, or use third party authentication that is trusted and secure (Log in with Google, OpenID, Oauth, Log in with Facebook, etc.)

Related

Custom salt generator in BCryptPasswordEncoder

I know that the salt we use to encrypt passwords should be :
They are algorithmically generated from some pieces of data associated with the user, for example, the timestamp that the user
created
They are randomly generated and stored in some form
They are plaintext or two-way encrypted along with the user's password record
Due to the first point, when anyone access to db, set his password for another user, he can not login instead of another user.
but when I use BCryptPasswordEncoder I replace my password in password column of another user and I can login by that user.
In my opinion, it is a security problem, because the admin that access to database can login instead of any user and may do some work. and these works is logged by that user not admin user.
If we use userId or userCreationTime or something like that to generate salt and override
PasswordEncoder#match method, the problem is resolved.
If these points are true my question is:
How can I use a custom salt generator in BCryptPasswordEncoder?
Salting is meant to prevent rainbow table attacks against leaked hashed passwords. With good per-user salting, one rainbow table will not work for the entire db, and an attacker needs to generate a rainbow table per user. This, combined with a computationally complex hashing algo, makes impractical to reverse engineer passwords from a leaked hashed password db.
If someone can manipulate the db, however, you are pwnz0r3d. If an admin can modify the db, they can modify user creation time. They can also "swap" user id with the known value.

How devise stores and read salts/hashes?

How does it work, that devise knows salts for encrypted passwords? Where does it store these hashes and how is that safe?
This is one of the main files for creating passwords: Devise::DatabaseAuthenticatable
Salt is not stored in the database, it is a string generated by this C program that is run by the BCrypt::Engine.generate_salt() function __bc_salt:
prefix = "$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW"
__bc_salt(prefix, cost, OpenSSL::Random.random_bytes(MAX_SALT_LENGTH))
This can be found here:
BCrypt::Engine
With some other interesting code here: BCrypt::Password
From what I can gather though, the salt itself is the 29 characters that appear after the third $ in the encrypted password. This alone cannot tell you the password though, since you also need to know the pepper which is based on your apps secret key (usually stored in your /config/initializers/secret_token.rb)
Conclusion: In order to decrypt a password, one would have to be using the right version of BCrypt, have obtained the secret token from the app, and have the encrypted password, and I think that at that point, user passwords are probably the least of your security concerns, so I think its pretty safe.

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

How to decrypt "Spring Security" password in grails?

I need to decrypt the password to send in email. Can anyone please guide me that how I can decrypt the "Spring Security" password in grails?
Thanks
Smac
Passwords aren't encrypted, implying that they can be decrypted, they're hashed. Hashing takes various inputs and generates a fixed-length output, so the process is lossy since a large original input cannot be stored completely within a small hash output.
But that's ok for passwords. Rather than decrypting (or "de-hashing") the stored password to see if a login attempt is valid, you hash the password from the login page and compare it to the stored hash value. These two don't have to be the same, and for example when using Bcrypt they won't be the same value, but the hash algorithm implementation will have logic to determine if two hashes are equivalent.
If you store passwords in a way that the original value can be retrieved, you might as well store them in cleartext. But that's crazy since then anyone with access to that table can see them.
As was mentioned in the comments, never send cleartext passwords by email. Instead configure a workflow where your users can reset their password. The http://grails.org/plugin/spring-security-ui plugin has this as a feature. If you don't want to use the whole plugin, feel free to steal the code for this feature. Basically the workflow is that a user requests a reset email for their username. Only ask for username, but not their email; use the one you already have. Generate a unique token and store it, and use it in the link in the email. When the user clicks the link you can validate the token and know that it wasn't just any arbitrary request from a hacker, but that it's from the user since you use their email address to verify their identity.
1) You should be using one way hashing algorithm for encrypting password Which can't be decrypted back. (Otherwise, its security threat for the application)
2) Text password should never be sent in emails. Infact, you should use workflow like sending the reset/forgot password link in the email.(The links can have UUId appended as a parameter for any new reset/forgot password request which is enough to identify).

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.

Resources