9
public Login authenticate(Login login) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            String password = login.getPassword();
            try {
                md.update(password.getBytes("UTF-16"));
                byte[] digest = md.digest();
                String query = "SELECT L FROM Login AS L WHERE L.email=? AND L.password=?";
                Object[] parameters = { login.getEmail(), digest };
                List<Login> resultsList = (getHibernateTemplate().find(query,parameters));
                 if (resultsList.isEmpty()) {
                         //error dude
                     }
                 else if (resultsList.size() > 1) {
                         //throw expections
                     }
                 else {
                       Login login1 = (Login) resultsList.get(0);
                       return login1;
                 }
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }                
       return null;  
    }

Exception

> java.lang.ClassCastException: [B
> cannot be cast to java.lang.String
>         at org.hibernate.type.StringType.toString(StringType.java:44)
>         at org.hibernate.type.NullableType.nullSafeToString(NullableType.java:93)
>         at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:140)
>         at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:116)
>         at org.hibernate.param.PositionalParameterSpecification.bind(PositionalParameterSpecification.java:39)
>         at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:491)
>         at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1563)
>         at org.hibernate.loader.Loader.doQuery(Loader.java:673)
>         at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
>         at org.hibernate.loader.Loader.doList(Loader.java:2213)
>         at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
>         at org.hibernate.loader.Loader.list(Loader.java:2099)
>         at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
>         at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
>         at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
>         at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
>         at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
>         at org.springframework.orm.hibernate3.HibernateTemplate$29.doInHibernate(HibernateTemplate.java:856)
>         at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:373)
>         at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:847)
>         at com.intermedix.services.LoginService.authenticate(LoginService.java:30)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:597)
>         at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:301)
>         at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
>         at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
>         at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
>         at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
>         at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
>         at $Proxy31.authenticate(Unknown Source)
>         at com.intermedix.ui.LoginDailog.checkLogin(LoginDailog.java:106)
>         at com.intermedix.ui.LoginDailog.access$0(LoginDailog.java:102)
>         at com.intermedix.ui.LoginDailog$2.handleAction(LoginDailog.java:88)
>         at com.vaadin.event.ActionManager.handleAction(ActionManager.java:228)
>         at com.vaadin.event.ActionManager.handleActions(ActionManager.java:198)
>         at com.vaadin.ui.Panel.changeVariables(Panel.java:345)
>         at com.vaadin.ui.Window.changeVariables(Window.java:1073)
>         at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariables(AbstractCommunicationManager.java:1094)
>         at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:590)
>         at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:266)
>         at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:476)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>         at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
>         at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
>         at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
>         at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
>         at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>         at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
>         at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
>         at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
>         at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>         at org.mortbay.jetty.Server.handle(Server.java:326)
>         at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
>         at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
>         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
>         at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
>         at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>         at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
>         at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
3
  • 2
    are you getting Compiler Errors? Warnings? Runtime Exceptions? Commented Jan 11, 2011 at 8:49
  • I have updated the question itself as i was getting expection Commented Jan 11, 2011 at 8:58
  • 3
    the error seems to be at the line 30 in this file. Which one is line 30? Commented Jan 11, 2011 at 9:02

4 Answers 4

7

Seems the password column of your database is a type mapped as a String in Java (varchar most probably). So hibernate cannot convert your byte array to a String.

You can change your lines to something like:

 String digest = new String(md.digest());
 String query = "SELECT L FROM Login AS L WHERE L.email=? AND L.password=?";
 Object[] parameters = { login.getEmail(), digest };

But it probably won't work as the digest will most certainly contain bytes not mappable to chars regardless of the encoding. You should probably use a base64 encoding to map you binary blob to a String.

Another solution will be to change your dabase scheme and make the password field a binary rather than a varchar.

In both cases you need to know how the password field is inserted in the database.

Some remarks on your code:

I find strange that you check the password by selecting a row from your database with both the username and the password. I'd though more logical to select using only the user and then validate the supplied password against the one returned on the database.

You use a hash function to ensure your password won't be stored in plain text in the database. That's good. However your scheme has a big flaw: if several users have the same password then the hashed password will be the same in the database. So if you have access to the database and know the password of one user it'll be really easy to find all the users sharing this password. In order to build something more secure you should use a password encoding scheme that include some salt.

Sign up to request clarification or add additional context in comments.

5 Comments

I don't get the meaning of using an additional salt for storing password hashs. If you do not opt for "security by obscurity" you'll have to provide all information to reconstruct the hash anyway? Could you give me a link for more information on this advice?
@mtraut in this case the main benefit of the salt is to ensure the uniqueness of the hashed passwords.
@mtraut in this case the main benefit of the salt is to ensure the uniqueness of the hashed passwords. The salt is chosen randomly when hashing the password and is prepended to the hashed password. You can have a look at aspirine.org/htpasswd_en.html for an implementation example. It select MD5 as algorithm and encrypt several time the same password you will see that the hashed password is different every time. In this hash scheme, the salt is the field between the $ after $apr1$. Check the link in the answer for more information.
I know what a salt does - what i doubt is that this improves the security in case of hashed password storage, at least in the case you mentioned. Computationally there's no big difference comparing a bunch of bytes or first extracting the salt, rehasing the known password and compare then (all in comparision to a brute force attack).
Yes you're quite right. It all depends on how many known passwords you want to check. If you have a default password and what to check if by any chance some users did forget to change it salt won't make a big difference. On the other hand if you are planning a dictionary attack on a database with several hundreds of users the salt will make a significant difference: a 2 day attack will turn in a 200 day attack with 100 users.
2

looks like you're [passing a byte array where a string was required.

try { login.getEmail(), new String(digest) }; instead of { login.getEmail(), digest };

refer http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#String%28byte[]%29

2 Comments

Won't work as the digest will certainly contain no char byte sequences.
@Nishant Thanks for sharing. new String("Any String") this solves my problem. Plus one for this.
0

The error seems to be in line 30, which I am guessing is the Object[] parameters line. In which case you need to convert the byte[] digest to String and use the string as the parameter.

this answer was given before the question was edited.

wrap things up in functions:

byte[] digest = getMessageDigest(login.getPassword());
login1 = verifyPassword(login.getEmail(), digest);

of course the relevant try/catch are still there.

Try to move away from the habit e.printStackTrace() to writing to log files with java.utils.logging.Logger or log4j.

try to have only one return in the function. if you keep the code the same, define Login login1=null at the start of the function, and simply assign in the else block. The return at the end should be return login1 (which would be null or some value).

the parts where you have code still to be implemented (e.g. error dude) should be commented with //TODO:. Most ides like eclipse/netbeans automatically find these comments as tasks.

Comments

0

Related to this error. In my case, I was mocking the String class in my test.

I had:

mockkStatic(Base64::class)
every { String(Base64.decode(text, 0)) } returns token

I changed it to:

mockkStatic(Base64::class)
every { Base64.decode(text, 0) } returns token.toByteArray()

So the String class behaved the way needed.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.