Apache-specific md5 javascript impelementation for .htpsswrd - javascript

I'm trying to save a username and password combo in a .htpsswrd file. Before I would send the username/password to the server to be saved by a php script, I would like to hash the password in MD5, so the plain password will not travel over http...
I have found a script, which will generate me an MD5 hash in javascript, but it is not accepted by the apache server as a valid password.
Here is what I'm always getting:
password: a
hash: 0cc175b9c0f1b6a831c399e269772661
What it should look like:
password: a
hash: $apr1$OcckEo.t$ohO2NxaQZm/YAcWfFZSLi.
This site: http://aspirine.org/htpasswd_en.html tells me, that the hash is made up from: Apache-specific algorithm using an iterated (1,000 times) MD5 digest of various combinations of a random salt and the password. This is the default (since Apache version 2.2.18).
All I would need, to have a function, that will hash me any string, and return the properly hashed reply.
And this is where I'm stuck! Anyone? :)

Well two points:
1-This Library might help with what you are trying to do.
2-My recommendation is to postpone the md5 to the server side script along with the salt. On the client side base64 encode the pass along with your own string operations if you wish (and make sure not to name the input name to password).
I always liked this method simply because it will be a pain in the ass for whoever that is trying to sniff around plus I can handle the passwords as I like server side with any further operations.
Good luck my friend

Related

Sending Email to Users without a risk

I need to send only special Users an Email. That is not a big amount. The Website must send 6 E-Mails a week. I found many solutions. I found this simple solution: https://medium.com/#edigleyssonsilva/cloud-functions-for-firebase-sending-e-mail-1f2631d1022e
When you look at the code, I need to fill out the variables. So I must type in my Email and the Password. As the web is opensource I think that is a very bad way. Do you know other simple solutions or know how to do this without typing in password?
With this solution you are using firebase functions. You most certainly want to set some environmental variables to protect some sensitives data like your gmail password.
You can do this in firebase: go check their documentation right here : https://firebase.google.com/docs/functions/config-env
The doc is going to help you set something like :
{
"mailer": {
"mail":"YOUR GMAIL ADRESS",
"password":"YOUR GMAIL PASSWORD"
}
}
So instead of you password in plain text you'll have this in your code :
'password': `${functions.config().mailer.password}`
Much safer right ?
The web is not open source. If you run a script in the browser then yes, the user can read the code. The example you link, however, runs on the server in response to HTTP(S) requests, and as such is not readable by a visitor.

Is my security design sound?

I have a specific need for security which means I'm writing more security-related code than I'm comfortable with. If what I'm doing is solved by a library somewhere, please, let me know and I'll drop my implementation immediately.
I have a server written in Java (actually Clojure) and a client written in JavaScript (actually ClojureScript) that runs as an Electron application. I need various clients applications to exchange information through the server ever being able to access that information: I need end to end encryption.
To implement end-to-end encryption I want to have a private public key-pair generated in the client and then the public key and an encrypted version of the private key will be uploaded to the server. Then, by doing a sort of challenge response in which the client signs a piece of random data and the server verifies it, the server would authenticate the user.
The registration process includes generating an Elliptic Curve Diffie Hellman key pair, specifically, P-521 (secp521r1) which seems to be a good choice according to https://security.stackexchange.com/questions/78621/which-elliptic-curve-should-i-use
After generating that, generate a 16 byte salt and then I pbkdf2 the password 872791 times with that salt, with a keylen of 32 and using sha512. Using the hashed key I encrypt the private key with aes-256-ctr. The last step is concatenating the salt length, the salt and the encrypted private key and send it to the server.
I'm assuming all of this happens over a TLS-secured channel, HTTPS, in which the validity of the certificate of the server is verified in the usual way, through the CAs. In the future I might use certificate pinning to increase security.
Is this a sound design? Does it look secure? Is there any or all of this that I could just delegate to a third party open source library that is well maintained?
My actual code:
(def elliptic-curve-name "secp521r1") ; https://security.stackexchange.com/questions/78621/which-elliptic-curve-should-i-use
(def encryption-algorithm "aes-256-ctr") ; http://lollyrock.com/articles/nodejs-encryption/
(def hash-bytes 32)
(def salt-bytes 16)
(def pbkdf-digest "sha512")
(def iterations 872791)
(defn encrypt-text [text key]
(let [salt (.randomBytes crypto salt-bytes)
salt-string (.toString salt "base64")
hashed-password (.pbkdf2Sync crypto key salt iterations hash-bytes pbkdf-digest)
text-cipher (.createCipher crypto encryption-algorithm hashed-password)
encrypted-text (gstring/format "%04d%s%s%s"
(count salt-string)
salt-string
(.update text-cipher text "utf8" "hex")
(.final text-cipher "hex"))]
encrypted-text))
(defn decrypt-text [encrypted-text key]
(let [salt-length (js/parseInt (subs encrypted-text 0 4) 10)
salt (.from js/Buffer (subs encrypted-text 4 (+ salt-length 4)) "base64")
hashed-key (.pbkdf2Sync crypto key salt iterations hash-bytes pbkdf-digest)
encrypted-text (subs encrypted-text (+ salt-length 4))
text-decipher (.createDecipher crypto encryption-algorithm hashed-key)]
(str (.update text-decipher encrypted-text "hex" "utf8")
(.final text-decipher "utf8"))))
(defn generate-key-pair [password]
(let [diff-hell (.createECDH crypto elliptic-curve-name)
public-key (.generateKeys diff-hell "base64")
private-key (.getPrivateKey diff-hell "base64")
encrypted-private-key (encrypt-text private-key password)]
[public-key private-key encrypted-private-key]))
This is an excellent start. These kind of questions are tricky and there is no way to prove these things secure. There are some good conceptual "pillars" to guide ones thoughs on it:
The pillars of security:
Privacy:
This code does not provide it. An attacker in the middle can read the structure of the message and can understand almost all of it. This gives them a strong stance. This system is open to replay attacks.
Authentication
By matching the password hash you are giving a strong assurance that this person does indeed know the password. PBKDF2 with a salt is state of the art and looks like you have this down.
Integrity:
This code does not provide it. the public key could be changed in flight. An attacker can substitute their own public key and cause the system to generate messages that they then could read. This attack is dependent on the rest of the system to detect the breach and respond to it, by comparing the public and private keys. This could open the system to known or unknown crypto attacks by allowing a "chosen key attack" which is generally considered dangerous. You really need to assure the integrity of the entire message. An attacker can take a password and key they do know along with a private key they do know, and switch them. Combined with replay attacks this will likely break the system.
Suggestions:
The structure of the entire message must be authenticated. There are two approaches to this. Either use a keyed MAC (Message Authentication Code) or use an "Authenticated Encryption" algorithm. MACs are included in more of the common crypto libraries. Don't roll your own MAC, and don't try to use a hash for this.
The privacy of the message should be ensured. This can be accomplished by ensuring that The message is send over TLS (you may already be doing this).
the message must include protection against replay attacks. This can be done in many ways. One strong way is to use a NONCE (Number used ONCe) so the server will only ever accept each message once. This must not be "per user" because many replay attacks are cross user.
The part you are absolutly doing correctly is asking for public scrutiny early in the process. This puts you way ahead of the industry norm. remember that
"Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can't break."
https://www.schneier.com/blog/archives/2011/04/schneiers_law.html
EDIT: make sure the password that protects them from you guessing their private key is not the same password you use to authenticate them (and that there is no way for them to use the same password)

protect http request URL

i am getting remote JSON value into to my client app as below.
var $Xhr = Ti.Network.createHTTPClient({
onerror : function($e) {
Ti.API.info($e);
},
timeout : 5000,
});
$Xhr.open("GET", "http://***********.json");
$Xhr.send();
$Xhr.onload = function() {
if ($Xhr.status == 200) {
try {
Ti.API.info(this.responseText);
} catch($e) {
Ti.API.info($e);
} finally {
$Xhr = null;
}
}
};
My json URL is static. i would like to protect this URL from stranger eyes after creating APK file or publishing for iOS.
Also my server side support PHP. I have thouhgt MD5, SHA etc. but i didn't develop any project about this algortim.
Do you have any suggestion or approach?
Thank you in advance.
I would just say that it is not possible for you to "hide" the end point. Your url will always to visible to the user because otherwise user's browser wouldn't know how to actually post it to your server.
If you meant to only hide the json object, even that is not totally possible. If your javascript knows what the values are then any of your client smart enough to understand javascript will be able to decode your encoded json object. Remember, your javascript has decoded object and a user would have full access to it. There is no protection against that. At best, you can hide it from everyday user by encoding to with md5 or sha as you put it.
I you wish to restrict access to app user only, you will need to authenticate your users first.
Once they are authenticated, you should generate a hash by concatenating userid (or any user identifying data) and a key that you know (a string will do it), and hashing it using any hashing method, md5 would be enough for that kind of usage I guess, SHA is good anyway.
The next step would be to send this hash with every AJAX request to your server. consider it as an additional data.
Finally, server-side, before treating the request and fetching the data to be sent, just generate a hash the same way you did in your app, using the userid of the requesting user and the same "secret" key you chose. You can now compare both hashes and see if they're identical. If not, then it's probably that someone tried to forge a request from outside your app.
Note that it could be possible for someone authenticated to get his hash (which depends on his ID) and then use it in one of his applications, so it may be a good idea to track the requests server-side in order to check if there's any suspicious usage of your API. You could aswell change your "secret key" regularily (forcing an update of your app though) or define an array with a different key for each day of the year in both your app and server code, so that each individual hashkey will change everyday, recurring each year.

Query a server for the existence of a record without the server knowing exactly what record was being queried for

I've been thinking about services such as pwnedlist.com and shouldichangemypassword.com and the fundamental problem with them - trust.
That is to say the user must trust that these services aren't going to harvest the submitted queries.
Pwnedlist.com offers the option to submit a SHA-512 hash of the users query which is a step forward but still leaks information if the query does exist in the database. That is, a malicious service would know that the given email address was valid (see also: why you should never click unsubscribe links in spam email).
The solution I came up with is as follows:
1) Instead of the user calculating and submitting the hash herself, the hash (I'll use the much simpler md5 in my example) is calculated via client side javascript:
md5("user#example.com") = "b58996c504c5638798eb6b511e6f49af"
2) Now, instead of transmitting the entire hash as a query to the server, only the first N bits are transmitted:
GET http://remotesite.com?query=b58996
3) The server responds with all hashes that exist in it's database that begin with the same N bits:
{
"b58996afe904bc7a211598ff2a9200fe",
"b58996c504c5638798eb6b511e6f49af",
"b58996443fab32c087632f8992af1ecc",
...etc... }
4) The client side javascript compares the list of hashes returned by the server and informs the user whether or not her email address exists in the DB.
Since "b58996c504c5638798eb6b511e6f49af" is present in the server response, the email exists in the database - inform the user!
Now, the obvious problem with this solution is that the user must trust the client side javascript to only transmit what it says it is going to transmit. Sufficiently knowledgable individuals however, would be able to verify that the query isn't being leaked (by observing the queries sent to the server). It's not a perfect solution but it would add to the level of trust if a user could (theoretically) verify that site functions as it says it does.
What does SO think of this solution? Importantly, does anyone know of any existing examples or discussion of this technique?
NOTE: Both pwnedlist.com and shouldichangemypassword.com are apparently run by reputable people/organizations, and I have no reason to believe otherwise. This is more of a thought exercise.
Services like pwnedlist.com are working with public information. By definition everyone has access to this data, so attempting to secure it is a moot point. An attacker will just download it from The Pirate Bay.
However, using a hash function like this is still easy to break because its unsalted and lacks key straighting. In all reality a message digest function like sha-512 just isn't the right tool for the job.
You are much better off with a Bloom Filter. This allows you to create a blacklist of leaked data without any possibility of obtaining the plain-text. This is because a permutation based brute force likely to find collisions than real plain text. Lookups and insertions a cool O(1) complexity, and the table its self takes up much less space, maybe 1/10,000th of the space it would using a traditional sql database, but this value is variable depending on the error rate you specify.

Simple XOR a message (Javascript/Tcl)?

I need the username/password to be scrambled at the client-side before sending it over via HTTP GET/POST. And the server will decode it with Tcl, before the checks against database.
Currently I'm thinking about using JavaScript for the client-side. Java Applet will also do.
Is there any way, that I can easily achieve it, using Simple XOR or any other methods? (Examples would be much appreciated)
I've found the few samples in C/Python/.NET/Java... But not in JavaScript and Tcl.
SSL is not an option to use, sadly.
If ssl is not an option, then I suggest the following scheme, which many sites use instead of SSL:
On the client side, combine the user name and password, then calculate a hash from it (MD5 is a popular choice).
Send the user's name and hash over to the server
On the server side, retrieve the password for that user from the database.
From the user name and password, calculate the hash and compare it with the client's hash. If the two match, then the passwords match.
For added security, add a little random text to the user+password mix. This random text, AKA the "salt", must be known on both the client and server sides.
Here is a suggestion on how to calculate the hash using MD5:
package require md5
proc calculateHash {user password salt} {
return md5:md5 -hex "$user:$salt:$password"
}
How to use it:
set user "johnny"
set password "begood2mama"
set salt "myDog_is_meaner_than_yourDog"
set hash [calculateHash $user $password $salt]
superNobody,
You should consider alternatives to storing plain-text passwords in the database. See:
http://www.codinghorror.com/blog/2007/09/youre-probably-storing-passwords-incorrectly.html
Instead of encoding the password in Javascript, then decoding the password in Tcl to compare with the database, you should consider SHA1 hashing in Javascript, and storing SHA1 hashed values in the database.
There are several available examples of a SHA1 hash function in javascript (just Google 'sha1 javascript'). The tcllib Tcl library has SHA1 support.
As HaiVu mentioned, you should also consider hashing / storing more than just a straight password hash, but instead use something like SHA1( username + websitename + password ). You can calculate this on the client in Javascript, and store it in the db.

Categories