Hasura Auth Clarifications - hasura

I have 2 things which i would like to confirm before moving forward with the workaround i have in mind.
When using JWT Auth with HS256 algorithm, i have a key which is less than 32 characters in length. I'm getting this error - "Error in $: Invalid JWK: Key size too small; should be at least 32 characters". So is this is an hard requirement ? or is there any trick to change this into a warning instead of an error ?
Is it possible for us to customise the Hasura Console Authentication from admin secret ? for lets say to SSO or anything ?

For the first one, yes it is a hard requirement. you can read more about it in RFC 7518
A key of the same size as the hash output (for instance, 256 bits for
"HS256") or larger MUST be used with this algorithm. (This
requirement is based on Section 5.3.4 (Security Effect of the HMAC
Key) of NIST SP 800-117 [NIST.800-107], which states that the
effective security strength is the minimum of the security strength of
the key and two times the size of the internal hash value.)

Related

Extending short key for AES256 (SNMPv3)

I am currently working on security of a switch that runs SNMPv3.
I am expected to code it in such a way, that any SHA (1 - 2-512) is compatible with any AES (128 - 256C).
Everything, like the algorithms alone, works pretty well. The problem is, that its been estabilished, that we are going to use SHA for key generation for both authentification and encryption.
When I want to use, let's say, SHA512 with AES256, there's no problem, since SHA has output of 64B and I need just 32B for key for AES256.
But when I want to use SHA1 with AES256, SHA1 produces only 20B, which is insufficient for the key.
I've searched the internet through and through and I found out, that it's common to use this combination (snmpget, openssl), but I havent found a single word about how are you supposed to prolong the key.
How can I extend the key from 20B to 32B so it works?
P. S.: Yes, I know SHA isn't KDF, yes, I know it's not that common to use this combination, but this is just how it is in my job assignment.
Here is a page discussing your exact question. In short, there is no standard way to do this (as you have already discovered), however, Cisco has adopted the approach outlined in section 2.1 of this document:
Chaining is described as follows. First, run the password-to-key algorithm with inputs of the passphrase and engineID as described in the USM document. This will output as many key bits as the hash algorithm used to implement the password-to-key algorithm. Secondly, run the password-to-key algorithm again with the previous output (instead of the passphrase) and the same engineID as inputs. Repeat this process as many times as necessary in order to generate the minimum number of key bits for the chosen privacy protocol. The outputs of each execution are concatenated into a single string of key bits.
When this process results in more key bits than are necessary, only the most significant bits of the string should be used.
For example, if password-to-key implemented with SHA creates a 40-octet string string for use as key bits, only the first 32 octets will be used for usm3DESEDEPrivProtocol.

symmetric AES enryption concept

i have a project for a website, running on Django. One function of it needs to store user/password for a third party website. So it needs to be symmetric encryption, as it needs to use these credentials in an automated process.
Storing credentials is never a good idea, I know, but for this case there is no other option.
My idea so far is, to create a Django app, that will save and use these passwords, and do nothing else. With this I can have 2 "webservers" that will not receive any request from outside, but only get tasking via redis or something. Therefore I can isolate them to some degree (they are the only servers who will have access to this extra db, they will not handle any web request, etc)
First question: Does this plan sound solid or is there a major flaw?
Second question is about the encryption itself:
AES requires an encryption key for all its work, ok that needs to be "secured" in some way. But I am more interested in the IV.
Every user can have one or more credential sets saved in the extra db. Would it be a good idea to use some hash of sort over the user id or something to generate a per user custom IV? Most of the time I see IV to be just random generated. But then I will have to also store them somewhere in addition to the key.
For me it gets a bit confusing here. I need key and IV to decrypt, but I would "store" them the same way. So wouldn't it be likely if one get compromised, that also the IV will be? Would it then make any difference if I generate the IV on the fly over a known procedure? Problem then, everyone could know the IV if they know their user id, as the code will be open source....
In the end, I need some direction guidance as how to handle key and best unique IV per user. Thank you very much for reading so far :-)
Does this plan sound solid or is there a major flaw?
The need to store use credentials is imho a flaw by design, at least we all appreciate you are aware of it.
Having a separate credential service with dedicated datastore seems to be best you can do under stated conditions. I don't like the option to store user credentials, but let's skip academic discussion to practical things.
AES requires an encryption key for all its work, ok that needs to be "secured" in some way.
Yes, there's the whole problem.
to generate a per user custom IV?
IV allows reusing the same key for multiple encryptions, so effectively it needs to be unique for each ciphertext (if a user has multiple passwords, you need an IV for each password). Very commonly IV is prepended to the ciphertext as it is needed to decrypt it.
Would it then make any difference if I generate the IV on the fly over a known procedure?
IV doesn't need to be secret itself.
Some encryption modes require the IV to be unpredictable (e.g. CBC mode), therefore it's best if you generate the IV as random. There are some modes that use IV as a counter to encrypt/decrypt only part of data (such as CTR or OFB), but still it is required the IV is unique for each key and encryption.

Is my password storage technique strong enough

This is a question about whether my security process is adequate for the kind of information i am storing.
I am building a website using ASP.NET 4.0 with a SQL backend and need to know how my security would hold up with regards to passwords and hashes etc.
I don't store any critical information on someone - No real names, addresses, credit card details or anything like that... just email and username.
For now, I am deliberately leaving out some specifics as I am not sure if telling you them will weaken my security but if not I can reveal slightly more.
Here is how I do it:
The user registers with their email and a unique username up to 50 chars long
They create a password (minimum 6 chars) using any characters on the keyboard (I HTMLEncode the input and am using parameterized stored procedures so I don't restrict the chars)
I send them an email with a link to verify they are real.
I use FormsAuthentication to set an auth cookie but I'm not using SSL at the moment... I understand the implications of sending auth details across plain http but I have asked my host to add the cert so it should be ready shortly.
It's the hashing bit I need to be sure of!
I create a random 100 character salt from the following char set (I just use the System.Random class, nothing cryptographic) - abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ0123456789!£$%^*()_{}[]#~#<,>.?
This is then merged with the password and then hashed using SHA-512 (SHA512Managed class) tens of thousands of times (takes nearly 2 seconds on my i7 laptop to generate the final hash).
This final hash is then converted to a base64 string and compared with the already-hashed password in the database (the salt is stored in another column in the DB too)
A few questions (ignore the lack of SSL for the moment, I just haven't bought the certificate yet but it will be ready in a week or so):
Does this strike you as secure enough? I understand there are degrees of security and that given enough time and resources anything is breakable but given that I don't store critical data, does it seem like enough?
Would revealing the actual number of times I hash the password weaken my security?
Does a 100 character salt make any difference over, say, a 20 character one?
By revealing how I join a password and salt together, would that weaken my security?
So, let's try to answer your questions one by one:
Does this strike you as secure enough? I understand there are degrees of security and that given enough time and resources anything is breakable but given that I don't store critical data, does it seem like enough?
No. It is definitely not "secure enough".
Without seeing code, it's hard to say more. But the fact that you're doing a straight SHA512 instead of doing a HMAC indicates one problem. Not because you need to be using a HMAC, but because most algorithms that are designed for this purpose use HMAC under the hood (for several reasons).
And it seems likely you're doing hash = SHA512(hash) (just from your wording) which is proven to be bad.
So without seeing code, it's hard to say for sure, but it's not pointing in the right direction...
Would revealing the actual number of times I hash the password weaken my security?
No, it shouldn't. If it does, you have a problem somewhere else in the algorithm.
Does a 100 character salt make any difference over, say, a 20 character one?
Nope. All the salt does is make the hash unique (forcing the attacker to attack each password separately). All you need is a salt long enough to be statistically unique. Thanks to the Birthday Problem, 128 bits is more than enough for a 1/10^12 chance of collision. Which is plenty for us. So that means that 16 characters is the upper bound on salt effectiveness.
That doesn't mean it's bad to use a longer salt. It just means that making it longer than 16 characters doesn't significantly increase the security it provides...
By revealing how I join a password and salt together, would that weaken my security?
If it does, your algorithm is severely flawed. If it does, it amounts to Security Through Obscurity.
The Real Answer
The real answer here is to not re-invent the wheel. Algorithms like PBKDF2 and BCRYPT exist for exactly this purpose. So use them.
Further Information (Note that these talk about PHP, but the concepts are 100% applicable to ASP.NET and C#):
YouTube Video - Password Storage and Hacking in PHP
Blog Post - The Rainbow Table Is Dead
Blog Post - Properly Salting Passwords
PHP password_hash RFC
Blog Post - Seven Ways To Screw Up BCrypt
In theory, your hashing scheme sounds ok. In practice, it sounds like you have rolled your own crypto, which is bad. Use bcrypt, scrypt, or pbkdf2. All of these are designed by security professionals.
Not really, but I don't think anyone needs to know that anyway.
No. It just needs to be unique to every user. The purpose of salt is to prevent precalculation of hashes/rainbow table attacks.
This doesn't apply once you make use of bcrypt (or scrypt or pbkdf2)
http://security.stackexchange.com has some topics on the subject, you should check them out.
Some extra notes - serious attackers will crack sha512 hashes way faster than your laptop. For example you could rent a server with a few Tesla GPU's from Amazon or similar, and start cracking at a few billion hashes/second rate. Scrypt makes some effort trying to prevent this by using memory intensive operations.
6 characters minimum for password is not enough, go with at least 8. A related image, I haven't verified the times but it gives a rough estimate and gives you the general idea (excluding dictionary attacks, which can target longer passwords):

Crypting with a weak secret key using AES

I am using AES to encrypt some data, the problem is that I have to use a key that contains only 4 digits (like pin code), so anyone can loop 9999 times to find my key and decrypt my text. The data I am encrypting here is an SMS.
Is the any idea to avoid this?
No, there isn't. You can add salts and iteration counts to a PBKDF all you want, but in the end the attacker only has 10K tries to go through, and that's peanuts.
The only sensible way to do this is to have a separate entity that performs the decryption. It can add secret entropy of its own to the key seed, and use a strong key. The entity would then place restrictions on the authentication with the PIN.
You might want to take a good look at your system's security architecture and see if you can change something to avoid this problem (access control, other login credentials etc. etc.).
Edit: Removed my comment about adding a salt, everyone who pointed this out was correct. You could perhaps increase the time complexity of decryption, such that a brute-force attack would take a prohibitively long time.
Edit: read this: https://security.stackexchange.com/questions/6719/how-would-you-store-a-4-digit-pin-code-securely-in-the-database
You can take the same aproach as ATM machines: after someone enters an incorrect PIN three times, that account is temprorarily invalid (you can also set a along time-out) and that user will have to undertake some kind of action (e.g. click a confirmation link in an e-mail) in order to reactive his/her account.
You'll also have to salt the PIN with an unique property of that user (preferably a string that was randomly generated when that user was registered). I also recommend adding an additional salt to all hashes that is either hard-coded or read from a config file (usefull in case your database is compromised but the rest isn't).
This approach still leaves you vulnerable to an attack where someone chooses a single PIN and brute-forces usernames. You can take some countermeasures to this by applying the same policy to IP-adresses, but that's still far from optimal.
EDIT: If your goal is to encrypt traffic rather than to hash PIN's, you should use HTTPS or another protocol based on public-key cryptography, that way you won't have to use your PIN for encrypting these SMS's.
assuming that you can only enter 4 digits, pad the keylength in the application with either phone number of sender or something like that?

Proper/Secure encryption of data using AES and a password

Right now, this is what I am doing:
1. SHA-1 a password like "pass123", use the first 32 characters of the hexadecimal decoding for the key
2. Encrypt with AES-256 with just whatever the default parameters are
^Is that secure enough?
I need my application to encrypt data with a password, and securely. There are too many different things that come up when I google this and some things that I don't understand about it too. I am asking this as a general question, not any specific coding language (though I'm planning on using this with Java and with iOS).
So now that I am trying to do this more properly, please follow what I have in mind:
Input is a password such as "pass123" and the data is
what I want to encrypt such as "The bank account is 038414838 and the pin is 5931"
Use PBKDF2 to derive a key from the password. Parameters:
1000 iterations
length of 256bits
Salt - this one confuses me because I am not sure where to get the salt from, do I just make one up? As in, all my encryptions would always use the salt "F" for example (since apparently salts are 8bits which is just one character)
Now I take this key, and do I hash it?? Should I use something like SHA-256? Is that secure? And what is HMAC? Should I use that?
Note: Do I need to perform both steps 2 and 3 or is just one or the other okay?
Okay now I have the 256-bit key to do the encryption with. So I perform the encryption using AES, but here's yet another confusing part (the parameters).
I'm not really sure what are the different "modes" to use, apparently there's like CBC and EBC and a bunch of others
I also am not sure about the "Initialization Vector," do I just make one up and always use that one?
And then what about other options, what is PKCS7Padding?
For your initial points:
Using hexadecimals clearly splits the key size in half. Basically, you are using AES-128 security wise. Not that that is bad, but you might also go for AES-128 and use 16 bytes.
SHA-1 is relatively safe for key derivation, but it shouldn't be used directly because of the existence/creation of rainbow tables. For this you need a function like PBKDF2 which uses an iteration count and salt.
As for the solution:
You should not encrypt PIN's if that can be avoided. Please make sure your passwords are safe enough, allow pass phrases.
Create a random number per password and save the salt (16 bytes) with the output of PBKDF2. The salt does not have to be secret, although you might want to include a system secret to add some extra security. The salt and password are hashed, so they may have any length to be compatible with PBKDF2.
No, you just save the secret generated by the PBKDF2, let the PBKDF2 generate more data when required.
Never use ECB (not EBC). Use CBC as minimum. Note that CBC encryption does not provide integrity checking (somebody might change the cipher text and you might never know it) or authenticity. For that, you might want to add an additional MAC, HMAC or use an encryption mode such as GCM. PKCS7Padding (identical to PKCS5Padding in most occurences) is a simple method of adding bogus data to get N * [blocksize] bytes, required by block wise encryption.
Don't forget to prepend a (random) IV to your cipher text in case you reuse your encryption keys. An IV is similar to a salt, but should be exactly [blocksize] bytes (16 for AES).

Resources