I am using Crypto.js in a project, I would like to be able to protect the password by obfuscating it, can this be done with crypto.js?
On Node.JS
You'd be better off to consider the password a config variable and treat it the same way you treat your other sensitive info - the DB connection info for example.
I like this tutorial which shows how you can get different config values for different environments that your node app runs in.
CryptoJS is an encryption library. You can certainly store an encrypted passphrase and the key that was used to encrypt the passphrase beside it. I would call that obfuscation. It's a very weak type of obfuscation, but it is one.
Related
I am learning about various hashing technique and found interesting library to start with cryptoJs
In the documentation, there are multiple options defined as below
hashing
HMAC
PBKDF2
Ciphers
Encoders
I understanding hashing is about generating the ciphertext. HMAC is about generating message authenticate code. But I am struggling to differentiate between PBKDF2, Ciphers, and Encoders. Which one to choose when?
Any pointers are helpful.
Password-Based Key Derivation Function 2 - PBKDF2 are functions used to create cryptographic keys that are harder to brute force using key-stretching. because humans are lazy and create passwords way too easy to brute force.
For example: our favorite password is "password"
Given a salt of "5C52FBAE9A4D97A49D14C8AF338DA55C"
The cryptographic key becomes
(Hex)A2EB261802FFD1965D034AC252E880A44955078D6D4F12EDCDF6D03549F0
(B64)ousmGAL/0ZZdA0rCUuiApElVB41tTxLtzfbQNUnw
try it here
It becomes apparent that the hash is not as easy to break as "password" on its own.
Nevertheless still possible with pre-computed hashes. You can see more here.
Ciphers on the other hand constitutes of methods for performing encryption as well as decryption. Some ciphers you see in cryptoJs are your basic AES, DES, triple DES etc.
Encoders are simply used for Encoding where encoding is very general. It is largely used to transform data so that another system can understand it. In the technology field, this is largely because every system architecture and technology has their own interpretations. Different applications will understand different encoding as per their need.
In Summary,
Encryption and Encoding are are designed 2 ways whereas PBKDF2 is a method of generating cryptographic keys (hashes) which are designed one way. Encoders are used to encode data into a form that can be transmitted or interpreted by another system.
Putting it in context:
If we want to store the password in a database we hash it because we do not need to know what the password is (no reversal required). However when we sent an encrypted mail to a friend we want to be able to reverse that encryption (decryption). Otherwise the content is lost. When the mail is sent, we added an attachment. The attachment is encoded in a way that other email clients can decode otherwise the other system cannot open up the attachment or will wrongly interpret the data sent.
So Encoding and Encrypting are similar in that encoded text and encrypted text can both be reversed. However, encoded text are meant to be reversed by anyone or any system that gets its hand on the encoded text since the encoding schemes are publicly available but encrypted text such as ciphertext are meant to be reversed only by certain specified individuals i.e. people who possess the key or decryption algorithms. In our example above, we want our attachment to be interpreted by any system but we do not want the content of the email including the attachment to be opened by everyone.
PBKDF2 is used when you want to hash a password but with the usual hashing functions, your password is vulnerable to dictionary attacks. So here comes PBKDF2 and salt.
Ciphers: Those are your normal encrypting functions. If you want to send some encrypted message where only the one with the right key can decrypt it.
Encoders: Are for text encoding formats.
NO. THAT SUGGESTION DOES NOT ANSWER THIS AT ALL. SEE CORRECT ANSWER BELOW.
I am building an application whereby I want a user to enter a password into a browser, which is sent via my server to another device running Python. The password then needs to be validated by the device running Python.
The problem is, I dont want my server handling passwords in any way. So I figured I could hash the password in the browser before it is sent, have the server pass on the hash to the device, then check the hash is equivalent on the Python side.
Python has a built-in library for this purpose, but it seems javascript does not. I thought I could leverage a public javascript library, but when I compare the results from the javascript SHA256 algorithm here to what the SHA256 function in Python produces it is not the same string of characters.
Is there a cross code hash function (or any other solution) I can use?
An Update
In response to a "gee whiz, this question is the same as all these ones" let me clarify. This is not about a strategy for storing passwords or finding a 'trustworthy' library (like the post suggested). There is NOT any discussion about cross code compatibility of SHA2 on this site. I could not even find a discussion that pointed out that different SHA2 implementations SHOULD produce the same result. I did plenty of research. In fact it was the various discussions about different javascript "implementations" of SHA2 that confused me. I actually tested a scenario myself, which further confused me as the website picked up a carriage return and produced a different hash. (see below)
This is about having a function in TWO languages that produces the same output...on different devices. I think it is actually an unusual application of hashing, as generally the same code layer is used to hash, store and compare hashed values.
In the rush to down-vote the question and establish mental superiority it seems to me the question was not read properly and incorrect assumptions were made. Hopefully contributors to this site will in future take a more considered and helpful approach like the successful answer.
The link for the javascript library I provided produced the following hash for the text 'MyPassword'
5e618e009fe35ea092150ad1f2c24e3181b4cf6693dc7bbd9a09ea9c8144720d
If I use the sha256 function from Python I get the result below, which seems to indicate to me that not all SHA256 functions are equal and produce the same result.
All proper implementations of SHA256 (or any hash/encryption) produce the same result if supplied with the same data. Your problem is solved by properly processing the data that you supply to the javascript library. The "5e61..." hash is a result of additional newline appended to the end of the "MyPassword" string, look:
In [1]: import hashlib
In [2]: hashlib.sha256(b'MyPassword').hexdigest()
Out[2]: 'dc1e7c03e162397b355b6f1c895dfdf3790d98c10b920c55e91272b8eecada2a'
In [3]: hashlib.sha256(b'MyPassword\n').hexdigest()
Out[3]: '5e618e009fe35ea092150ad1f2c24e3181b4cf6693dc7bbd9a09ea9c8144720d'
For the future, popular implementations of hashes and cryptographic algorithms are thoroughly tested, and if the answer seems wrong - it's probably because your data is wrong.
To enable message-level encrpytion in Pubnub, one would include the cipher key when instantiating PubNub on the client.
var pubnub = PUBNUB({
publish_key: 'my_pubkey',
subscribe_key: 'my_subkey',
cipher_key: 'my_cipherkey'
});
The PubNub docs then state:
Never let your cipher key be discovered, and be sure to only exchange it / deliver it securely. On JavaScript, this means explicitly don't allow anyone to View Source or View Generated Source or Debug to enable viewing your cipher key.
Exactly how would one completely obfuscate a cipher key in a web page? It is not possible to completely prevent someone from viewing the source, only make it inconvenient. Any encryption/decryption routines on the client can also be identified fairly easily.
What exactly is the suggested route we should take here?
I am not familiar with pubnub, but in cases similar to this, you can create a hash or some other reference that points to the secret on your server. So the hash is shared between client/server, and the server references the hash as your key.
You have not said what your server side language is, but there are a number of different hashing mechanisms available, SHA-1 or similar is recommended https://en.wikipedia.org/wiki/SHA-1
That's exactly the point: you cannot ever publish your cipher_key on the web under any circumstances. Websites may use their API given the other (public) keys, but the cipher_key must only be used from environments that are secure.
Let's say I have am creating a webapp, where users can create a nested tree of strings (with sensitive information). These strings are presumably quite short. I want to encrypt both keys and values in this tree before saving it. All values in the tree will be encrypted client-side using a symmetric key supplied by the user. Likewise they will be decrypted client-side, when reading.
The tree is persisted in a Mongo database.
I can't decide whether I should serialize the tree and encrypt it has a whole string or whether to encrypt values individually, considering that all data in the tree will be encrypted using the same key.
What are the pros and cons of either?
From what I can tell, AES uses a block size of 128 bits, meaning that any string can grow up to 15 characters in length when encoded, which speaks in favor of encoding a serialized string (if you want to avoid overhead)
Note: Although the webapp will use both HTTPS, IP whitelisting and multifactor authentication, I want to make an effort to prevent data breach in the event the Mongo database is stolen. That's what I'm going for here. Advice or thoughts on how to accomplish this is appreciated.
Update
Furthermore, I also want my service to inspire trust. Sending data in the clear (although over HTTPS) means the user must trust me to encrypt it before persisting it. Encrypting client-side allows me to emphasize that I don't know (or need to know) what I'm saving.
I can't think of a reason why these approaches would be different in terms of security of the actual strings (assuming they are both implemented correctly). Encrypting the strings individually obviously means that the structure of the tree will not be secret, but I'm not sure if you are concerned with that or not. For example, if you encrypt each string individually, someone seeing the ciphertexts could find out how many keys there are in the tree, and he could also learn something about the length of each key and value. If you encrypt the tree as a whole serialized blob, then someone seeing the ciphertext can tell roughly how much data is in the tree but nothing about the lengths or number of individual keys/values.
In terms of overhead, the padding would be a consideration, as you mentioned. A bigger source of storage overhead is IVs: if you are using a block cipher mode such as CTR, you need to use a distinct IV for each ciphertext. This means if you are encrypting each string individually, you need to store an IV for each string. If you encrypt the whole serialized tree, then you just need to store the one IV for that one ciphertext.
Before you implement this in Javascript, though, you should make sure that you're actually getting a real improvement in security from doing client-side encryption. This article is a classic: http://www.matasano.com/articles/javascript-cryptography/ One important point is to remember that the server is providing the Javascript encryption code, so encrypting data on the client doesn't protect it from the server. If your main concern is a stolen database, you could achieve the same security by just encrypting the data on the server before inserting it in the database.
First of all, I am not a security expert ;-)
I can't decide whether I should serialize the tree and encrypt it has a whole string or whether to encrypt values individually, considering that all data in the tree will be encrypted using the same key.
I would say serializing the tree first and encrypting the result of that has the biggest con.
What plays a huge role in successfully cracking encryption is often the knowledge about certain characters that appear quite often in the original text – for example the letters e and n in English language – and doing statistical analysis based on that on the encrypted text.
Now lets say you use for example JSON to serialize your tree client-side before encrypting it. As the attacker, I would easily know that, since I can analyze your client-side script at my leisure. So I also know already that the “letters” {, }, [, ], : and " will have a high percentage of occurrence in every “text” that you encrypt … and that the first letter of every text will have been either a { or a [ (based upon whether your tree is an object or an array) – that’s already quite a bit of potentially very useful knowledge about the texts that get encrypted by your app.
(xposted from nodejs#googlegroups.com)
what's the best locally stored authentication scheme?
i've found a few:
http://dailyjs.com/2011/01/10/node-tutorial-9/
github.com/ncb000gt/node.bcrypt.js/tree/master/examples
github.com/Turbo87/locomotive-passport-boilerplate/blob/master/app/models/account.js
(which looks like it came from the bcrypt example)
it looks like mongoose-auth implement from bcrypt's example as well:
github.com/bnoguchi/mongoose-auth/blob/master/lib/modules/password/plugin.js
and, i can't figure out how everyauth is generating passwords.
github.com/bnoguchi/everyauth/blob/master/lib/modules/password.js
... and i've found tons that generate based on Math.random(Date.now *
some_number).... something like that - didn't look right so i don't
exactly remember.
what's the best method for doing this security wise?
Locally storing authenticated credentials is one of the worst possible ways to authenticate clients. In order to pull this off you need to use cryptography, which introduces the possibility of brute force. A good example of how this goes horribly wrong is the Oracle Padding Attack used against .Net.
If you want a secure system you won't implement this. If you want something that isn't very secure but probably will work then you should use an HMAC. Bcrypt, block ciphers, and stream ciphers are really not the right choice. You can implement an HMAC with bcrypt, but i would choose another hash function like sha256.
Also, the current date time is NOT A RANDOM VALUE, this should never be relayed upon for the calculation for a random value. You will need to keep track of the time so that the session token can expire. Your secret should be generated with an entropy store like /dev/random