Securing hashing algorithm

  • Thread starter Thread starter Wm. Scott Miller
  • Start date Start date
W

Wm. Scott Miller

Hello all!

We are building applications here and have hashing algorithms to secure
secrets (e.g passwords) by producing one way hashes. Now, I've read alot
and I've followed most of the advice that made sense. One comment I've seen
alot about is "securing the hashing routine" but no-one explains how to
accomplish this. So how do I secure my hashing routine? Do I use code
access security, role based security, ACLs, etc or combination? And if
combination what combination is the best? The routines will be used by two
"applications." A ASP.NET and a Windows application. It already has a
strong name and is installed in the GAC. How do I prevent it from being run
by any code besides our two applications? Should it be installed in the
GAC? And if not, how to I guarantee the two applications are using the same
version?

Thanks for your help,
Scott
 
Wm. Scott Miller said:
Hello all!

We are building applications here and have hashing algorithms to secure
secrets (e.g passwords) by producing one way hashes. Now, I've read alot
and I've followed most of the advice that made sense. One comment I've seen
alot about is "securing the hashing routine" but no-one explains how to
accomplish this. So how do I secure my hashing routine?


Scott

Disregard that piece of advice "securing the hashing routine" - publish your
hashing routine for all to see, and then and only then can you be sure that
it is a *good* algorithm.

regards
roy
 
If you use microsoft's hashing algorithms, you dont have to worry about that.
It comes with the SDK.
 
When using one way hashing like this, you always have one issue - securing
the password/key passed to the keyed hash. I assume your using a "keyed"
hash like HMACSHA1 or a keyed MD5 to hash your secret. Some options are:
1) string encrypted in your program using obfuscator (better then nothing,
but probably not great.)
2) Protected via ACLs in registry, file or smartcard (or others).
3) Use DPAPI to set and get your password in the OS. See
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/secmod/html/secmod21.asp

Of the three, DPAPI is probably the best. It is still not perfect as a user
logged in using same user account as app used can decrypt the data. If you
use the machine store, any user could decrypt the data unless you use
additional entropy. So possible a slightly better approach may be to use
machine store so any user on local machine could use your program and keep
your "entropy" encrypted in your program (via obfuscator encryption.) So
not a hacker needs to hack your assembly to figure out general idea of what
your doing, somehow decrypt your entropy (i.e. second pw) and then figure
out how to get data from DPAPI and what store your used, etc. As you can
see, you could keep jumping through hoops hiding data until your blue and
still not get 100% protection.
Possibly a better approach is to use RSA private/public key and client only
knows public key. That way, you have nothing you need to hide. You still
need to protect your client apps public key so it can't be replaced by a
hackers public key, etc.

Naturally, none of this matters if your code is plain .net as hacker can use
ildasm and ilasm to round trip your code and do remove your protections and
public key removing the strong name checking at assembly load time. Only
thing that helps this is obfuscating using a good one (I use and like
XenoCode which also prevents ildasm on your assemblies). Getting to a point
where the only option for the hacker is to hack your code is probably the
best effort and should be the goal I would think.
 
Roy:

We are using an already verified *good* algorithm but have added "spice and
salt" to the routine. This was done to make the routine "slow" enough to
make dictionary attacks a lengthy process.

Scott
 
I've noticed by searching the groups that you are a strong supporter of the
"keyed" approach. So, what are the advantages and disadvantages of using
keyed vs non-keyed hashes?

Thanks,
Scott
 
Well in my mind, when using non-keyed hash, you don't need a password to
create the same the hash using the same data. So anyone can look at your
code and figure out you are just using sha (for example) to create your hash
and do the same. Keyed hash gives you a level of security as you need to
know the "key" to gen the same hash. Its like needing to know the password.
Now you need to secure the "shared" password as both sides need to use the
same one. Unfortunately, this means you need to embed it in your code or in
a resource. So you could "hide" it in multple parts of your app and/or use
obfuscator crypto on the string or strings you will combine to create your
clear password. You could then use something like a combination of DPAPI
and the ISO store to store the encrypted key. So you need to be the user
who stored the key and the assembly (I think using ISO) to retreive the key.
The issue is still the first part - where to store the password so I can get
it, encrypt it, and store it? I keep coming back to string crypto using
obfuscator, but maybe there is a better way? Naturally, you may be able to
avoid the above by using PKI public key method. It would depend on what
your doing I guess. Anyway, hth.

From MS HMACSHA1 docs:
"...A keyed hash algorithm is a key-dependent, one-way hash function used as
a message authentication code. Only someone who knows the key can verify the
hash. Keyed hash algorithms provide authenticity without secrecy.

Hash functions are commonly used with digital signatures and for data
integrity. HMACSHA1 is an example of a keyed hash algorithm."
 
Correct me if I'm wrong, but storing the password using DPAPI is a good idea
in theory and does make for an extra step for the hacker, but encypting
anything using DPAPI is meaningless in the case of a web server being
compromised on port 80 because the hacker will be running under the context
of the user account that the web server is running which has access to any
DPAPI encrypted values. Additionally, any hacker with their salt (sorry, no
pun intended), will know the DPAPI approach due to is popularity.

The DPAPI option only assists in the case where the server can be
compromised from another server/computer/service. This is where, when using
DPAPI with a user account, the "key" will be protected. If these are not
concerns because of other counter measures taken, then DPAPI is a waste of
time to implement, except for the "defense in depth" argument.

So ***if*** port 80 is the only attack vector, DPAPI provides very limited
additional protection because key or non-keyed routines are equally
compromised with a hacker really wanting to get in.

Is this right or am I missing something?

Scott
 
Correct me if I'm wrong, but storing the password using DPAPI is a good
idea
in theory and does make for an extra step for the hacker, but encypting
anything using DPAPI is meaningless in the case of a web server being
compromised on port 80 because the hacker will be running under the context
of the user account that the web server is running which has access to any
DPAPI encrypted values. Additionally, any hacker with their salt (sorry, no
pun intended), will know the DPAPI approach due to is popularity.

(Thinking out load. Please correct if wrong.) If that is the concern then
nothing you do would help. A hacker would need to somehow gain command
level access to your machine via port 80 to be able to exec os commands,
call APIs, etc - no? Is there such an existing attack in IIS/web services?
If there is, millions have bigger issues for a start. So for rest of talk,
lets assume that is not possble (as if it were, we would just unplug our
boxes and wait for a fix or take our chances.) Not sure if it matters if
dpapi is popular or not. It was introduced in NT 4.0 I think but did not
work in somel cases from what I read. W2K and latter was when people really
started using it so not sure it is that popular yet. However it still needs
to standup to popular use, else it is not worth anything as you say.

I could keep spinning here, but still not exactly what your trying to do.
Could you outline (from client to server and back) what your trying to do
exactly and what techs you want to use? Example:
1) Windows client gets password and hashes via xyz using shared secret, etc.
2) Client calls IIS web service for xyz.
3) Web server does xyz and returns xyz to client.
4) ...
Using only IIS web services at server? What about WSE and security? What
about SecureXML? Using web services at Windows client? Some more detail
would help drive further talk. Thanks for interesting discussion.
 
As for the existance of such a vunerability, I would have to say yes
considering that most of the security sites I read say stuff like "complete
compromise of the server" next to IIS. That to me sounds like being able to
get access to os commands. That is of course for a vunerability that has a
patch, but as we have seen in the past several months/years more and more
vunerabilities are being discovered in almost all software on production
systems worldwide. (Most companies are starting to think of
security....Microsoft being the biggest company to finally jump on board)
With that in mind, there is the **possibility** that such a vunerability
still exists and has not been discovered/patched yet. As long as we patch
our systems and keep them up-to-date, the probability of such an attack
becomes more remote, but not altogether impossible.

The original question, was on the line of the "prudent man rule" and was a
query about securing the actual DLL that contains the code of the routine.
On those lines, is that something I should worry about? And, if so, what
should I look into, research, do to accomplish the most secure environment
in the least amount of time. In my reaserch into web site security, they
say that the more elements that are available to the cracker, the more
likely they are to be able to obtain the information you are securing. So,
I'd like to make it as hard as possible to obtain:

1. Actual hashes stored in my system
2. Algorithm I use to generate hashes
3. Their own hashes for dictionary attacks

Number 2 was the issue of the original question as I have a pretty good (I
think) plan for #1 and #3 because of my research. Your point on using a
"keyed hash" interested me because it holds the possibility of increasing
the security of the hashes, which is why I wanted to know more. But all new
things have to be held up against the questions "What does this buy me?" and
"Is it worth the time and money to implement?" That is maybe why I came
across a so dead set against "keyed hashes" but I was just looking into the
first question. I'm still interested in the keyed approach, I'm not sure if
it buys me any more security, though, because in all my research, you are
the first place I've heard to use them (which doesn't mean much as I haven't
real every security article on the web).

So maybe we can approach it this way:

What will keyed hashes buy me in terms of security?

AND

How long will it take to implement and is it worth that much time and money
based on the answer to question #1?

Scott
 
The original question, was on the line of the "prudent man rule" and was a
query about securing the actual DLL that contains the code of the routine.
On those lines, is that something I should worry about? And, if so, what
should I look into, research, do to accomplish the most secure environment
in the least amount of time. In my reaserch into web site security, they
say that the more elements that are available to the cracker, the more
likely they are to be able to obtain the information you are securing. So,
I'd like to make it as hard as possible to obtain:

1. Actual hashes stored in my system
2. Algorithm I use to generate hashes
3. Their own hashes for dictionary attacks

Again would need to know what your hashing exactly and what your sending.
What is the protocol? If your just hashing a password in sha or md5 and
sending that, then that is no better then sending the clear password as I
could just capture the hash and use that in my own requests using your
password. DNS, for example, uses HMAC-MD5 to prove a requester knows a key.
The whole request is hashed using the shared HMAC and added to the
additional section. The server hashes the request (minus the key record)
and compares hashes. Only the owner of the shared key could have produced
the same hash over the data (hopefully.) There are many ways to go. But I
would settle on something ~standard and in general use instead of creating
your own. SRP (rfc2945) may be what you need. Can't find any c# examples
currently, maybe the gnu library. Can anyone produce a c# srp library and
post it?

http://srp.stanford.edu/
http://www.faqs.org/rfcs/rfc2945.html
 
You know all those sites you go to and register and then log in with a
username and password? That is what we are talking about. Nothing fancy.

Scott
 
Back
Top