java.lang.ClassCastException:[B不能强制转换为java.lang.String

我编写了一个带有Field LoginId和Password的权限类。

Iam使用AES_ENCRYPT加密passwrd并在db中加载它。

我想只检索解密的密码。 所以,我在OPEN JPA 2.0中使用NAEDQueryis使用AES_DECRYPT。

我写的查询是:

Query q = em.createNativeQuery("select AES_DECRYPT(l.password,?2) from loginDetails l where l.loginID = ?1"); q.setParameter(1, loginId); q.setParameter(2, getKey()); String s = q.getSingleResult(); 

但我得到以下例外:

 java.lang.ClassCastException: [B cannot be cast to java.lang.String at com.rcs.chef.validation.UserValidation.decryptedPasswordForID(UserValidation.java:99) at com.rcs.chef.validation.UserValidation.validateUser(UserValidation.java:81) at com.rcs.chef.validation.UserValidation.activate(UserValidation.java:72) 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.apache.aries.blueprint.utils.ReflectionUtils.invoke(ReflectionUtils.java:226) at org.apache.aries.blueprint.container.BeanRecipe.invoke(BeanRecipe.java:824) at org.apache.aries.blueprint.container.BeanRecipe.runBeanProcInit(BeanRecipe.java:636) at org.apache.aries.blueprint.container.BeanRecipe.internalCreate(BeanRecipe.java:724) at org.apache.aries.blueprint.di.AbstractRecipe.create(AbstractRecipe.java:64) at org.apache.aries.blueprint.container.BlueprintRepository.createInstances(BlueprintRepository.java:219) at org.apache.aries.blueprint.container.BlueprintRepository.createAll(BlueprintRepository.java:147) at org.apache.aries.blueprint.container.BlueprintContainerImpl.instantiateEagerComponents(BlueprintContainerImpl.java:640) at org.apache.aries.blueprint.container.BlueprintContainerImpl.doRun(BlueprintContainerImpl.java:331) at org.apache.aries.blueprint.container.BlueprintContainerImpl.run(BlueprintContainerImpl.java:227) 

我甚至试过这个:

 Query q = em.createNativeQuery("select AES_DECRYPT(l.password,?2) from loginDetails l where l.loginID = ?1"); q.setParameter(1, loginId); q.setParameter(2, getKey()); List s = q.getResultList(); String s1 = null; for(Object o : s){ s1= (String) o; } 

即使在这里也可以获得相同的例外:

 java.lang.ClassCastException: [B cannot be cast to java.lang.Object 

你能告诉我处理req的查询和错误是什么吗?

类似的问题: 什么样的Java类型是“[B”?

MySQL的AES_DECRYPT不返回String ,而是返回字节数组,用“[B”表示。 将结果转换为byte[]并从中构建字符串。

看起来你甚至不需要解密密码; 你只想validateUser ,对吧? – 在这种情况下,正如其他人所指出的那样,应该使用安全哈希。

您可以使用MySQL轻松完成此操作,因为它已经提供了必要的function :MD5(被认为是不安全的),SHA1(非常标准)和SHA2(甚至比SHA1更安全)。

所以你的方案基本上可能看起来像:

insert into loginDetails (..., passwordHashSalt, passwordHash) values ( ..., ?1, SHA1(CONCAT( ?1, ?2 )) ) ,其中?1设置为唯一的’salt’,可用于例如,用户名本身, ?2是实际密码。 请注意,salt也必须存储在DB中,并且“必须”对每个用户/密码都是唯一的; 因此,用户名是一个自然的选择。

然后,要validation给定的密码,您可以执行以下操作:

select 'OK' from loginDetails where ... and passwordHash = SHA1(CONCAT( passwordHashSalt, ?1 )) ,其中?1是要validation的密码。

有关更多信息,请在互联网上搜索“密码哈希”,例如, 此处或此处 。

如果需要,也可以在数据库客户端代码中完成这些散列操作。