How can I secure a password so that it is hidden in Orca?
Short answer is no, so it's a question of how secure you need to be.
If you want to secure the values from casual observers, use code such as the Crypto API to store the encrypted value in the property table at build time and decrypt it into another property at install time. This is not totally secure because a determined user could reverse-engineer your decryption code in the MSI custom action and figure out what you're doing. It's "security by obscurity". You could perhaps obfuscate your code also.
Make sure you declare all the properties as Hidden in WiX so they are not exposed in an installation log file.
If this is a corporate environment, perhaps you could arrange to get the passwords from a secure location at install time, again into properties marked Hidden ao they are not in the MSI file at all.
Related
My problem:
I need, basic authentication over HTTP (client can't afford HTTPS). So I don't worry if communication is not encrypted. I just want to prevent some user from sniffing and using the password (site only used to upload photos and those photos are public.).
Toolbox of what I have at my disposal:
Javascript
PHP
Sha512.js
The SHA algorithm is the same in both PHP and JS:
The proof:(?)
<?php
$password= "password";
echo hash('sha512',$password);
//outputs: b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86
?>
While in JS (all my files are encoded in utf8)
document.getElementById("hiddenField").value
= JS.sha512("password");
//outputs b109f3bbbc244eb82441917ed06d618b9008dd09b3befd1b5e07394c706a8bb980b1d7785e5976ec049b46df5f1326af5a2ea6d103fd07c95385ffab0cacbc86
However I cannot simply send the same hash on every connection, else anyone can sniff it and send it to connect.
So my idea was to use password_hash() function as salt generator.
The salt is public, the hash of (password+salt) is public, but password is private and never sent as clear text: the server will compute (hopefully) the same hash as the one in JS from the client and verify that both hashes match.
The problem is that regardless of what I do, I'm unable to get the same output when I hash the output of that function(password_hash). It seems to be something related to encoding.
I want to use password_hash() because it already keeps into account a lot of security stuff:
Javascript:
document.getElementById("hiddenField").value
= JS.sha512("password" + document.getElementById("publicToken").value);
I put the "password_hash" content into another hidden form field that I call "publicToken". Regardless of what I do I'm unable to get the hash match:
<?php
$salt = ut8_encode(password_hash("another_password")); //doesn't work either
In the end, what do I have to do to get a correctly encoded salt?
<?php
$salt = //... one time usage salt.. but what to put here?
I realize your client cannot afford a standard HTTPS certificate, but honestly, even a free SSL certificate is likely to be far better than what ever you can concoct here.
In this situation, all you are doing is making the browser-side hash the user's password, and all one has to do to get in is send a matching hash. If you decide to do this, you definitely need to hash the password again on the server side, but it is still no replacement for SSL.
More on it here: https://crackstation.net/hashing-security.htm
Without public key cryptography and a way to verify the identity of the server (in other words, HTTPS), the unfortunate truth is that there is simply no way to secure the communication to an acceptable level. I would not even advise trying, for fear of getting a false sense of security. No matter how much you hash and salt, it will only be minimally better than sending the plaintext password and trivial to break.
If your client cannot afford a certificate, I would recommend taking a look at StartSSL. Their basic level certificates are completely free; I believe they're valid for 1 year with unlimited renewal.
Another project worth looking at is Let's Encrypt. They've trying to make the process of getting a certificate much simpler and more accessible, so they've developed a way to completely automate the process of issuing (free) certificates. The service is not live yet, unfortunately; they plan to start issuing certificates this summer. Quoting their page:
Anyone who has gone through the trouble of setting up a secure website
knows what a hassle getting a certificate can be. Let’s Encrypt
automates away all this pain and lets site operators turn on HTTPS
with a single click or shell command.
When Let’s Encrypt launches in mid-2015, enabling HTTPS for your site
will be as easy as installing a small piece of certificate management
software on the server:
$ sudo apt-get install lets-encrypt
$ lets-encrypt example.com
That’s all there is to it! https://example.com is immediately live.
The Let’s Encrypt management software will:
Automatically prove to the Let’s Encrypt CA that you control the website
Obtain a browser-trusted certificate and set it up on your web server
Keep track of when your certificate is going to expire, and automatically renew it
Help you revoke the certificate if that ever becomes necessary.
No validation emails, no complicated configuration editing, no expired
certificates breaking your website. And of course, because Let’s
Encrypt provides certificates for free, no need to arrange payment.
I have a wordpress theme that I support and upgrade frequently.
It contains a built in upgrader routine that takes a zip file containing the updated files and extracts to the theme directory, overwriting the old files.
I'd like to add a license verification routine to this upgrader routine that asks for the users's email address and password, then does a remote call to my member's database and verifies that the email and password are valid before allowing the routine to continue.
Is this a simple task? What approach would you take? The upgrade request will come from anywhere on the net and will have to call back to my server for the verification.
Its very similar to what WPRobot does to validate upgrades with known email addresses.
Your suggested method is just security through obscurity. The user can easily remove the client-side license check. If you have to do this, a simple way is to use HTTP Basic Auth. Have the client request the zip file with their credentials, and respond with the zip (correct credentials) or 401 Authorization Required (otherwise).
I am trying to use hashing for a test case in tomcat-users.xml. (I plan on implementing a subclass of one of the Realm classes to do the real authentication with auditing, logging, etc.) I ran the command
$TOMCAT_HOME/bin/digest.sh -a sha secret
and got the result 'secret:e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4'. I pasted this into the
<user password="e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4" roles="test" username="tester"/>
line. I added the appropriate magic words to my web.xml to use DIGEST authentication for the servlet (role = test), but when I try logging in, I get a 401 error.
I "watched" the transactions with wireshark, and it seems the browser is sending all of the right responses.
Am I doing this right? It seems to me that the digest authentication will send back MD5("username:realm:password"), so there is no way for tomcat to compare the value stored in the tomcat-users.xml file with the value sent by the browser, since it would require either "unhashing" the password value from tomcat-users.xml or "username:realm:password".
Should I be storing the hash of "username:realm:password" instead?
Boy, that was a DUE (dumb user error)!
I should have read the tomcat docs more carefully:
If using digested passwords with DIGEST authentication, the cleartext used to generate the digest is different. In the examples above {cleartext-password} must be replaced with {username}:{realm}:{cleartext-password}. For example, in a development environment this might take the form testUser:localhost:8080:testPassword.
Exactly the last part of my own question :-).
Using a provided username, password, and domain name, how can I retrieve a boolean value indicating if a user has successfully authenticated with a primary domain controller? Authentication should be performed using the Kerberos protocol for windows domain controllers. Thanks in advance, Dan
There's a free implementation of a windows-only JAAS login module and of an SSO Negotiate (Kerberos/NTLM) authenticator: Waffle.
You need to either write your own or use third party Authentication Module for that. When I was doing this, there was nothing available from JDK, so I used this tool. Note that it's GPL, but you can learn from there. You will have to create conf. file describing your authentication module and feed it into your JVM with java.security.auth.login.config property (e.g. using -D, or either way). In case of Tagish it looks something like this:
NTLogin
{
com.tagish.auth.win32.NTSystemLogin required returnNames=true returnSIDs=false defaultDomain="domain";
};
Another thing you will need is to specify kerberos configuration file via java.security.krb5.conf property. I don't have the details of this file handy, but you can easily find it on the net -- google about for krb5.conf. Settings in this file will have to match your windows domain and other windows specific settings.
It's a bit tricky to configure, but for me it worked very well, pretty robust.
I would like to use an LDAP server (probably Apache directory) to manage logins and credentials for an application. From time to time the application needs to work offline (on a laptop) without a connection to the LDAP server.
What is the best way to replicate the credentials localy?
I have already thought about:
Using Mitosis to replicate the LDAP server on the laptop.
But it would be a quite "heavy" and complicated solution. Moreover Mitosis seems not be be finished yet.
Exporting the credentials as LDIF file that could be stored on the laptop.
But I would need a way to check that the LDIF file actually comes from the LDAP server (The file should include a kind of signature). Moreover I would like to reject LDIF files that haven't be updated for more than a week. It would be nice if I could avoid implementing signing and age check myself.
Any other ideas or tools that could help me?
Edited Edit: I had a look at Kerberos because the documentation of the Java-Kerberos-API seems to say that it is possible to use a cached ticket in a local cache and I thought this might be a solution for me. Moreover Kerberos can be added as plugin to Apache Directory.
But the Kerberos cache stores decrypted tickets (aiming at sharing them with other applications). I would need the crypted version of the ticket to be able to check the user password during an offline session. Conclusion: Kerberos doesn't offer a simple solution to my problem.
Knowing that it will be probably ok if the user have to log on once online before being able to log on offline, consider the following algorithm:
user provides your application with a (username + password)
application attempts to contact LDAP for authentication
working online? (e.g. connection successful)
application authenticates against LDAP using (username + password)
authentication succesful?
application stores or updates hash(password) as (cached_credentials) for (username) into local secure storage
application proceeds as authenticated [[STOP]]
authentication failed?
application proceeds as non-authenticated (incorrect credentials) [[STOP]]
working offline? (e.g. network error)
application attempts retrieve (cached_credentials) for (username) from local secure storage
(cached_credentials) exists AND more recent than (1 week)?
application compares (cached_credentials) against hash(password)
match?
application proceeds as authenticated [[STOP]]
no match?
application proceeds as non-authenticated (incorrect credentials) [[STOP]]
(cached_credentials) does not exist OR less recent than (1 week)?
application proceeds as non-authenticated (network error) [[STOP]]
This is (or was, IIRC), by the way, the same model employed by Windows NT+ for user authentication against domain controllers. Upon login an attempt is made to authenticate against the domain controller and create or update the local (cached) version of the user profile. If the domain controller is not available, the user is prompted to proceed with authentication against the credentials captured in the local (cached) profile (if one exists.)
EDIT
Yes, this is, in spirit, the same solution as copying an ldif file locally, except that you do not have to parse ldif when you're offline. :)
It is understood that you can store any additional attributes (permissions, etc.) in your cache
It is also understood that 'secure storage' is at least signed. :) You can do this easily enough with a SHA-1 hash and a secret, or you can use full-fledged cryptographic providers available on your platform (or in Java, if using Java.) You do not need to crypt it as long as no secret information is stored inside.
Here is the solution I decided to use (I have already described it in an edit to my question, but I would like to able to accept an answer to "close" the question):
As I have not found another solution, I decided to use an LDIF export, add a timestamp as comment at the beginning of the file and then sign the file. To sign the file I calculate an hash value (SHA-1) of the file + a secret key. The signature is added as comment at the beginning of the file. To check the signature I remove the first line of the signed file and recalculate the hash value.