Lets say I have a origin server which through the act of a redirect with particular query string params needs to provide details to a target server. However, I need to ensure those details came from my origin server only.
Also I can't sure the integrity of the target server. Or specifically, the target server might be compromised so any encryption keys might have been read by a malicious party.
I'm thinking I could sign the query string using some form of public/private keypair. The origin server uses a private key to sign the string, and the target server uses a public key to verify it came from my origin server, and the message hasn't been tampered with.
I'm far from a cryptography expert or anything, so any assumption here I've made might be wrong, please correct me if so :)
I'm basically after a (hopefully) simple way to do this in Ruby.
Probably, the easiest form of signing the query data (in your case a redirection URL) is by using an HMAC. Your origin and destination server would need to share a common key in this case - HMACs are not a form of public/private key cryptography, but rather a form of keyed hashing.
The module you're looking for is ruby-hmac, and your source and destination server would have to do something like:
require 'hmac-md5'
HMAC::MD5.new("<your shared key>").update("<your URL to check>").hexdigest
and compare on the destination side that the digest computed by the HMAC on the source side is equivalent: both sides thus do the same computation. The hexdigest of the HMAC can simply be transported by an additional query parameter from source to destination.
Related
I am trying to implement a basic authentication system for a Go server that consists of users with multiple server-generated passwords (tokens essentially) which must be securely stored in a database.
One way of accomplishing this would be to hash the passwords with a one-way function and a globally unique salt.
However, since users have multiple passwords in my case, this creates a problem for authentication; each of the user's passwords would likely have a different salt, so the server would need to iterate through the passwords in the database, hash the supplied password using the same salt as the one in the database, and then compare. This does not seem efficient.
Alternatively, I was thinking that I could relax the "globally unique" constraint on the salt and randomly generate a salt when the user is created, and use it for all that user's passwords. With this, I would only need to hash the user-supplied password once, and could then use an SQL query to perform authentication. This is also the solution suggested in this related question.
However, the Go x/crypto/bcrypt package does not expose a function which hashes passwords with a custom salt, its salt generation is private. Is this for a good reason? Are there vulnerabilities with this approach of using a common salt for all of a user's passwords?
This problem seems common enough given that sites like GitHub and GitLab would have to deal with it for their personal access token storage, yet it appears that GitLab (by default) simply performs a sha256 hashing on their generated tokens.
By design each hash would have it's own salt, this is stored in the database. as a string with the salt, password hash, bcrypt passes etc. It appears all or most newer gen cryptography does this so each hash would have to be cracked individually. If you want something stored in your code I'd add a pepper to every password and then let their salts be unique in the db.
You're worried about efficiency of iterating over each password but I wouldn't be, security is probably better than your login efficiency. Just store their login session for x days?
Are there vulnerabilities
Well yes, bcrypt itself is considered vulnerable if that's an answer?
I think you should go with argon2id since it is what is considered "good" today, and since your program is new
https://pkg.go.dev/golang.org/x/crypto/argon2
This is a wrapper so it is safe as far as the Go crypto is concerned, and very easy to use:
https://github.com/alexedwards/argon2id
If you're wanting tokens you should probably use UUIDs
I'm using codeigniter2.1.4.my problem is when i use
$this->encrypt->encode($row['service_id'])
in my view page ,it generates such a key that is not permitted url and i also want short encrypt key bcoz current encrypt key too big.Any solution?Thanks
A simple solution would be to send the encrypted key as a POST parameter instead of GET parameter. In case you do not want to do that, look into
$config['permitted_uri_chars']
in application/config/config.php. Add the characters that you want to send in URL. Remember. THIS IS A SECURITY COMPROMISE.
You can always change to another cipher algorithm using
$this->encrypt->set_cipher();
This is known to mess up your sessions as sessions are encrypted using the default algorithm. So if you set session, change cipher and again try modify or set session, it wont work. You need to make sure you set back the cipher to default after your encryption is done.
Check and try to understand system/libraries/Session.php, especially around the line
$cookie_data = $this->CI->encrypt->encode($cookie_data);
If you are interested in finding answer to "WHY"
I am using OpenSSL HMAC SHA256 method to sign all my requests to the server generating a HASH using a private key. My requests look like:
www.myserver.com/url/to/resource?par1=val1&par2=val2&par3=val3&hash=GENERATEDHASH
So my server calculates a hash using the parameters and the same key, if the hashes match he considers that the request is OK.
I want to sign the responses (using a HTTP header maybe) too. My idea is to calculate the hash using the content of the response and add that hash to the header, so my other side can validate that response before processing it.
Any ideas on how to do that?
You might want to emulate Amazon's way of doing it?
http://docs.aws.amazon.com/AWSECommerceService/latest/DG/rest-signature.html
The AntiForgeryToken is used to prevent CSRF attacks, however the links on MSDN don't give me much insight to what exactly the AntiForgeryToken does, or how it works, or why things are done the way they are.
From what I gather, it creates a hash inside a web page and a cookie. One or both of them use the hashed IPrincipal.Name, and use symmetric encryption.
Can anyone shed light as to:
How the AntiForgeryToken works internally
What should it be used to protect
What should it NOT be used to protect
What is the reasoning behind the implementation choices for #1 above?
Example:
is the implementation safe from "DoubleSubmit" cookies and other common vulnerability
Are there implementation issues if the user opens multiple tabs
What makes MSFT's implementation different from the one available at SANS
Okay, here is my best shot.
1) Internally, mvc uses RNG crypto methods to create a 128 bit string to act as the XSRF token. This string is stored in a cookie as well as in a hidden field somewhere on the form. The cookie name seems to be in the form of __RequestVerificationToken + a base 64 encoded version of the application path(server side). The html part of this uses the AntiForgeryDataSerializer to serialize the following pieces of data
- salt
- value(the token string)
- the ticks of the creation date
- the username (seems like Context.User)
The validate method basically deserializes the values out of the cookie and that of the form and compares them based on the values (salt/value/ticks/username).
2/3) I would think this discussion is more for when to use XSRF tokens and when not to. In my mind, you should use this on every form (I mean why not). The only thing I can think of that this doesn't protect is if you have actually hit the form in question or not. Knowing the base64 encoding of the app name will allow the attacker to be able to view the cookie during the XSRF attack. Maybe my interpretation of that is incorrect.
4) Not sure exactly what you are looking for here? I guess I would have built a mechanism where I would try and store the XSRF token in the session (if one was already available) and if not, then try the cookie approach. As for type of crypto used, I found this SO artcile.
Pros and cons of RNGCryptoServiceProvider
Let's say an application has really specific data which belongs to a user, and nobody is supposed to see it except the owner. I use MySQL database with DataMapper ORM mapper. The application is written in Ruby on Sinatra.
Application behavior:
User signs up for an account. Creates username and password.
Logs into his dashboard.
Some fields in specific tables must be protected.
Basically, I'm looking for auto-encryption for a model properties. Something like this:
class Transaction
include DataMapper::Resource
property :id, Serial
property :value, String, :length => 1024, :encrypted => true
... etc ...
belongs_to :user
end
I assume that encryption/decryption on the fly will cause performance problems, but that's ok. At least if that works - I'm fine.
Any ideas how to do this?
I wouldn't store any data that relies on the user remembering their password and then using that password to decrypt the data. What are you going to do when the user changes their password? Decrypt/Encrypt everything? I doubt it. What if the admin reset the password? All data lost? Again, I doubt it.
See the other links about storing secrets but please don't use any value from the user as part of your encryption.
So you want to store the data encrypted in the database? Firstly, I would ask you to consider why you need to do this? You should be able to write your application such that only the authenticated user can get to their own data.
If you do genuninely need to store encrypted data, that you also need to be able to decrypt (as opposed to a one-way hash) then there is lots about encryption in ruby here: http://www.example-code.com/ruby/encryption.asp
You certainly should encrypt/decrypt data on user side - otherwise there is no point in encrypted storage, as tracks of private data still there somewhere - in network cache, in swapfiles of different kind etc. Moreover, data can be sniffed with Man-In-The-Middle attack.
So what you probably want is javascript-based client-side encryption. Topic is greatly covered in http://javascript.about.com/library/blencrypt.htm (Rijndael encryption algorithm), and there is great AES implementation library on http://www.movable-type.co.uk/scripts/aes.html
You should encrypt data before submission of form (with onClick callback of "Submit" button f. e.), and then pass to server and process as usual.
Drawback is that you can't use any Rails with such data - only client-side javascript.
I had to do this for encrypting sensitive data. I wrapped the strongbox gem and it's on github: http://github.com/bitzesty/safe
The safe gem provides Public Key Encryption of AR attributes.
You use a one-way hashing algorithm. Hash the password and store the hash. Then whenever the user enters his password, you hash the password entered and compare it to the stored hashed password. If they're the same, you let them through. If not, they're denied.
It's generally not a good idea to ever store a user's password that can be taken to plaintext.
Typically it is stored as a salted hash of either MD5 or SHA1.
So, you have a random salt, store it in the user's table, and then you hash their pass and the salt, like this:
$hash = md5(md5(salt) + pass)
I would recommend against storing a pass that can be returned, the only way I'd recommend you store it is in a one way hash.
That said, there are some encryption schemes that you can use, such as RSA encrytion. This way, your application will encrypt the user's password that it receives from the end user using your public key, and when you need to decrypt it, do so using your private key. There's really very limited application for storing a key this way (such as providing a log in to another site automatically) and is typically frowned upon.
attr_encrypted may be also solution for encryption sensitive data, works with ruby class or ActiveRecord, DataMapper, or Sequel in Rails.
https://github.com/attr-encrypted/attr_encrypted