You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Mark2008 <mh...@gmail.com> on 2008/11/28 18:06:58 UTC

WS-Security [UserNameToken] against encrypted database password

I am integrating the WS-Security UserNameToken approach to our existing
application. The existing application stores the password in one-way hashing
format with the following code snippet (plaintext is the plain password text
and we use https)

------------------------------------------------------
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(plaintext.getBytes("UTF-8"));
byte raw[] = md.digest();
String hash = (new BASE64Encoder()).encode(raw);
String newPassword = hash.substring(0,19); 
------------------------------------------------------

I tried both PasswordDigest and PasswordText, but the security token can not
be authenticated.
WSSecurityException: The security token could not be authenticated or
authorized at
org.apache.ws.security.processor.UsernameTokenProcessor.handleUsernameToken(UsernameTokenProcessor.java:129)

How do I specify the encrypt/hash algorithm? or should I hash the
INPUT-password using the above code first and then set the database hashed
password WSPasswordCallback.setPassword or just bypass the
WSPasswordCallback.handleUserNameToken by comparing those two
programmatically?

Any idea? What's the best practice? 

Thanks,

Mark

-- 
View this message in context: http://www.nabble.com/WS-Security--UserNameToken--against-encrypted-database-password-tp20737774p20737774.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WS-Security [UserNameToken] against encrypted database password

Posted by Mayank Mishra <ma...@gmail.com>.
Mark2008 wrote:
> I am integrating the WS-Security UserNameToken approach to our existing
> application. The existing application stores the password in one-way hashing
> format with the following code snippet (plaintext is the plain password text
> and we use https)
>
> ------------------------------------------------------
> MessageDigest md = MessageDigest.getInstance("SHA");
> md.update(plaintext.getBytes("UTF-8"));
> byte raw[] = md.digest();
> String hash = (new BASE64Encoder()).encode(raw);
> String newPassword = hash.substring(0,19); 
> ------------------------------------------------------
>
> I tried both PasswordDigest and PasswordText, but the security token can not
> be authenticated.
> WSSecurityException: The security token could not be authenticated or
> authorized at
> org.apache.ws.security.processor.UsernameTokenProcessor.handleUsernameToken(UsernameTokenProcessor.java:129)
> How do I specify the encrypt/hash algorithm? or should I hash the
> INPUT-password using the above code first and then set the database hashed
> password WSPasswordCallback.setPassword or just bypass the
> WSPasswordCallback.handleUserNameToken by comparing those two
> programmatically?
>   

Hi Mark,

You can use either of Password Digest or Password Hash, it should work. 
You can provide a PasswordCallBackHandler class, and can set Password 
for the Identifier as UserName_Token.

The security entropy of Username Token is less hence I remember that I 
read somewhere that they are not recommended to be used for Signature 
and Encryption operations.

With Regards,
Mayank
> Any idea? What's the best practice?
> Thanks,
>
> Mark
>
>   


Re: WS-Security [UserNameToken] against encrypted database password

Posted by Glen Mazza <gl...@gmail.com>.

Mark2008 wrote:
> 
> Hi Mayank,
> 
> Thanks for the reply. 
> 1. It works if I set the WSPasswordCallback.setPassword in my
> PasswordCallbackHandler class to the plain-password-text for both
> PasswordDigest and PasswordText method. 
> 
> 2. If I uses the hashed password (loaded from our database) in my
> PasswordCallbackHandler class, it throws exception. 
> 
> 3. The password I passed in is absolutely right because I am able to login
> to the web application using that uid/pwd. 
> 
> How does the UsernameTokenProcessor.handleUsernameToken know how to handle
> the hashed-password-text from the dabase? They may uses different
> algorithm to hash and store to database. The code snippet I posted is the
> what we uses to hash the password before store it to database.
> 

I believe if you're using SSL anyway, it is best to use a plaintext password
because of the very problem that you're giving, namely, that password digest
requires that the client use the same hash algorithm as the database,
information that you normally don't want to give out (or is otherwise
strange to give out).  In the book SOA Security (Manning publ.) this very
point is given as the main disadvantage to the password digest format.

Basically, if the password you are comparing against is stored in the DB in
encrypted format, use the plaintext passwords over SSL for the SOAP call.

Glen

-- 
View this message in context: http://www.nabble.com/WS-Security--UserNameToken--against-encrypted-database-password-tp20737774p20741394.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WS-Security [UserNameToken] against encrypted database password

Posted by Mark2008 <mh...@gmail.com>.
Hi Mayank,

Thanks for the reply. 
1. It works if I set the WSPasswordCallback.setPassword in my
PasswordCallbackHandler class to the plain-password-text for both
PasswordDigest and PasswordText method. 

2. If I uses the hashed password (loaded from our database) in my
PasswordCallbackHandler class, it throws exception. 

3. The password I passed in is absolutely right because I am able to login
to the web application using that uid/pwd. 

How does the UsernameTokenProcessor.handleUsernameToken know how to handle
the hashed-password-text from the dabase? They may uses different algorithm
to hash and store to database. The code snippet I posted is the what we uses
to hash the password before store it to database.

Can you explain more on your idea? I am a little bit confused.

Thanks,

Mark2008 wrote:
> 
> I am integrating the WS-Security UserNameToken approach to our existing
> application. The existing application stores the password in one-way
> hashing format with the following code snippet (plaintext is the plain
> password text and we use https)
> 
> ------------------------------------------------------
> MessageDigest md = MessageDigest.getInstance("SHA");
> md.update(plaintext.getBytes("UTF-8"));
> byte raw[] = md.digest();
> String hash = (new BASE64Encoder()).encode(raw);
> String newPassword = hash.substring(0,19); 
> ------------------------------------------------------
> 
> I tried both PasswordDigest and PasswordText, but the security token can
> not be authenticated.
> WSSecurityException: The security token could not be authenticated or
> authorized at
> org.apache.ws.security.processor.UsernameTokenProcessor.handleUsernameToken(UsernameTokenProcessor.java:129)
> 
> How do I specify the encrypt/hash algorithm? or should I hash the
> INPUT-password using the above code first and then set the database hashed
> password WSPasswordCallback.setPassword or just bypass the
> WSPasswordCallback.handleUserNameToken by comparing those two
> programmatically?
> 
> Any idea? What's the best practice? 
> 
> Thanks,
> 
> Mark
> 
> 

-- 
View this message in context: http://www.nabble.com/WS-Security--UserNameToken--against-encrypted-database-password-tp20737774p20739494.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WS-Security [UserNameToken] against encrypted database password

Posted by Mark2008 <mh...@gmail.com>.


Mark2008 wrote:
> 
> I am integrating the WS-Security UserNameToken approach to our existing
> application. The existing application stores the password in one-way
> hashing format with the following code snippet (plaintext is the plain
> password text and we use https)
> 
> ------------------------------------------------------
> MessageDigest md = MessageDigest.getInstance("SHA");
> md.update(plaintext.getBytes("UTF-8"));
> byte raw[] = md.digest();
> String hash = (new BASE64Encoder()).encode(raw);
> String newPassword = hash.substring(0,19); 
> ------------------------------------------------------
> 
> I tried both PasswordDigest and PasswordText, but the security token can
> not be authenticated.
> WSSecurityException: The security token could not be authenticated or
> authorized at
> org.apache.ws.security.processor.UsernameTokenProcessor.handleUsernameToken(UsernameTokenProcessor.java:129)
> 
> How do I specify the encrypt/hash algorithm? or should I hash the
> INPUT-password using the above code first and then set the database hashed
> password WSPasswordCallback.setPassword or just bypass the
> WSPasswordCallback.handleUserNameToken by comparing those two
> programmatically?
> 
> Any idea? What's the best practice? 
> 
> Thanks,
> 
> Mark
> 
> 

-- 
View this message in context: http://www.nabble.com/WS-Security--UserNameToken--against-encrypted-database-password-tp20737774p20743275.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WS-Security [UserNameToken] against encrypted database password

Posted by Mark2008 <mh...@gmail.com>.
Thanks very much for the help. 

I did not read the PasswordText part carefully and thought the validation
for plain password text is also delegated to CXF. It works after making the
change.

Mark

Glen Mazza wrote:
> 
> Again, I would send a plaintext password over HTTPS (my tutorial is using
> DIGEST for passwords, but it is an easy switch to plaintext)--it will be
> encrypted along with everything else in the soap:envelope that way, but
> with plaintext your web service provider will get the actual password and
> can use it to validate against the database, using whatever mechanism you
> database provides to authenticate (or you can use the same hash with the
> plaintext pwd that you already use to stored the hashed version in the
> database table.)
> 
> As shown in the WS-Security guide in the CXF documentation[1], you'll
> notice the password verification function is designed differently if you
> use a plaintext password instead of a password digest--as for how you can
> validate, take a look at the password verification function for plaintext
> passwords and I think that will answer your question.
> 
> HTH,
> Glen
> 
> [1]
> http://cwiki.apache.org/CXF20DOC/ws-security.html#WS-Security-UsernameTokenAuthentication
> 
> 
> 
> Mark2008 wrote:
>> 
>> Hi Glen,
>> 
>> Thanks for your reply.
>> 
>> Here is our situation:
>> 
>> 1. We use HTTPS for encryption
>> 2. The password value in our database is hashed, NOT encrypted. So I can
>> not decrypt it back its original value and uses
>> WSPasswordCallback.setPassword.
>> 
>> I guess the typicaly way will NOT work unless the client know what
>> hashing function we are using and then send the generated hashed value
>> through the web service. 
>> 
>> Is there anyway I can bypass the WSPasswordCallback.handleUserNameToken
>> (or other methods) that validate the INPUT-password against the supplied
>> hashed value from database? 
>> 
>> For example, If I can get the INPUT-password, I can hash it with the
>> algorithm at server side and then compare with the database value. This
>> should be very simple.
>> 
>> Or is it possible I can modify/update the INPUT-password with its hashed
>> value at server side?
>> 
>> Thanks for your help,
>> 
>> Mark
>> 
>> Mark2008 wrote:
>>> 
>>> I am integrating the WS-Security UserNameToken approach to our existing
>>> application. The existing application stores the password in one-way
>>> hashing format with the following code snippet (plaintext is the plain
>>> password text and we use https)
>>> 
>>> ------------------------------------------------------
>>> MessageDigest md = MessageDigest.getInstance("SHA");
>>> md.update(plaintext.getBytes("UTF-8"));
>>> byte raw[] = md.digest();
>>> String hash = (new BASE64Encoder()).encode(raw);
>>> String newPassword = hash.substring(0,19); 
>>> ------------------------------------------------------
>>> 
>>> I tried both PasswordDigest and PasswordText, but the security token can
>>> not be authenticated.
>>> WSSecurityException: The security token could not be authenticated or
>>> authorized at
>>> org.apache.ws.security.processor.UsernameTokenProcessor.handleUsernameToken(UsernameTokenProcessor.java:129)
>>> 
>>> How do I specify the encrypt/hash algorithm? or should I hash the
>>> INPUT-password using the above code first and then set the database
>>> hashed password WSPasswordCallback.setPassword or just bypass the
>>> WSPasswordCallback.handleUserNameToken by comparing those two
>>> programmatically?
>>> 
>>> Any idea? What's the best practice? 
>>> 
>>> Thanks,
>>> 
>>> Mark
>>> 
>>> 
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/WS-Security--UserNameToken--against-encrypted-database-password-tp20737774p20758246.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WS-Security [UserNameToken] against encrypted database password

Posted by Glen Mazza <gl...@gmail.com>.
Again, I would send a plaintext password over HTTPS (my tutorial is using
DIGEST for passwords, but it is an easy switch to plaintext)--it will be
encrypted along with everything else in the soap:envelope that way, but with
plaintext your web service provider will get the actual password and can use
it to validate against the database, using whatever mechanism you database
provides to authenticate (or you can use the same hash with the plaintext
pwd that you already use to stored the hashed version in the database
table.)

As shown in the WS-Security guide in the CXF documentation[1], you'll notice
the password verification function is designed differently if you use a
plaintext password instead of a password digest--as for how you can
validate, take a look at the password verification function for plaintext
passwords and I think that will answer your question.

HTH,
Glen

[1]
http://cwiki.apache.org/CXF20DOC/ws-security.html#WS-Security-UsernameTokenAuthentication



Mark2008 wrote:
> 
> Hi Glen,
> 
> Thanks for your reply.
> 
> Here is our situation:
> 
> 1. We use HTTPS for encryption
> 2. The password value in our database is hashed, NOT encrypted. So I can
> not decrypt it back its original value and uses
> WSPasswordCallback.setPassword.
> 
> I guess the typicaly way will NOT work unless the client know what hashing
> function we are using and then send the generated hashed value through the
> web service. 
> 
> Is there anyway I can bypass the WSPasswordCallback.handleUserNameToken
> (or other methods) that validate the INPUT-password against the supplied
> hashed value from database? 
> 
> For example, If I can get the INPUT-password, I can hash it with the
> algorithm at server side and then compare with the database value. This
> should be very simple.
> 
> Or is it possible I can modify/update the INPUT-password with its hashed
> value at server side?
> 
> Thanks for your help,
> 
> Mark
> 
> Mark2008 wrote:
>> 
>> I am integrating the WS-Security UserNameToken approach to our existing
>> application. The existing application stores the password in one-way
>> hashing format with the following code snippet (plaintext is the plain
>> password text and we use https)
>> 
>> ------------------------------------------------------
>> MessageDigest md = MessageDigest.getInstance("SHA");
>> md.update(plaintext.getBytes("UTF-8"));
>> byte raw[] = md.digest();
>> String hash = (new BASE64Encoder()).encode(raw);
>> String newPassword = hash.substring(0,19); 
>> ------------------------------------------------------
>> 
>> I tried both PasswordDigest and PasswordText, but the security token can
>> not be authenticated.
>> WSSecurityException: The security token could not be authenticated or
>> authorized at
>> org.apache.ws.security.processor.UsernameTokenProcessor.handleUsernameToken(UsernameTokenProcessor.java:129)
>> 
>> How do I specify the encrypt/hash algorithm? or should I hash the
>> INPUT-password using the above code first and then set the database
>> hashed password WSPasswordCallback.setPassword or just bypass the
>> WSPasswordCallback.handleUserNameToken by comparing those two
>> programmatically?
>> 
>> Any idea? What's the best practice? 
>> 
>> Thanks,
>> 
>> Mark
>> 
>> 
> 
> 

-- 
View this message in context: http://www.nabble.com/WS-Security--UserNameToken--against-encrypted-database-password-tp20737774p20753211.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: WS-Security [UserNameToken] against encrypted database password

Posted by Mark2008 <mh...@gmail.com>.
Hi Glen,

Thanks for your reply.

Here is our situation:

1. We use HTTPS for encryption
2. The password value in our database is hashed, NOT encrypted. So I can not
decrypt it back its original value and uses WSPasswordCallback.setPassword.

I guess the typicaly way will NOT work unless the client know what hashing
function we are using and then send the generated hashed value through the
web service. 

Is there anyway I can bypass the WSPasswordCallback.handleUserNameToken (or
other methods) that validate the INPUT-password against the supplied hashed
value from database? 

For example, If I can get the INPUT-password, I can hash it with the
algorithm at server side and then compare with the database value. This
should be very simple.

Or is it possible I can modify/update the INPUT-password with its hashed
value at server side?

Thanks for your help,

Mark

Mark2008 wrote:
> 
> I am integrating the WS-Security UserNameToken approach to our existing
> application. The existing application stores the password in one-way
> hashing format with the following code snippet (plaintext is the plain
> password text and we use https)
> 
> ------------------------------------------------------
> MessageDigest md = MessageDigest.getInstance("SHA");
> md.update(plaintext.getBytes("UTF-8"));
> byte raw[] = md.digest();
> String hash = (new BASE64Encoder()).encode(raw);
> String newPassword = hash.substring(0,19); 
> ------------------------------------------------------
> 
> I tried both PasswordDigest and PasswordText, but the security token can
> not be authenticated.
> WSSecurityException: The security token could not be authenticated or
> authorized at
> org.apache.ws.security.processor.UsernameTokenProcessor.handleUsernameToken(UsernameTokenProcessor.java:129)
> 
> How do I specify the encrypt/hash algorithm? or should I hash the
> INPUT-password using the above code first and then set the database hashed
> password WSPasswordCallback.setPassword or just bypass the
> WSPasswordCallback.handleUserNameToken by comparing those two
> programmatically?
> 
> Any idea? What's the best practice? 
> 
> Thanks,
> 
> Mark
> 
> 

-- 
View this message in context: http://www.nabble.com/WS-Security--UserNameToken--against-encrypted-database-password-tp20737774p20743382.html
Sent from the cxf-user mailing list archive at Nabble.com.