我编写了一个带有字段 LoginId 和 Password 的实体类。

我正在使用 AES_ENCRYPT 加密密码并将其存储在数据库中。

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

我写的查询是:

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<Object> 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.xml 的错误是什么吗?

请您参考如下方法:

类似问题:What kind of Java type is "[B"?

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

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

您可以使用 MySQL 轻松做到这一点,因为它已经提供了必要的 functions : MD5(被认为不安全)、SHA1(非常标准)和 SHA2(甚至比 SHA1 更安全)。

所以你的方案基本上可能如下所示:
insert into loginDetails (..., passwordHashSalt, passwordHash) values ( ..., ?1, SHA1(CONCAT( ?1, ?2 )) ) ,其中 ?1设置为唯一的“salt”,例如用户名本身,以及 ?2是实际密码。请注意,盐也必须存储在数据库中,并且“必须”对每个用户/密码都是唯一的;因此,用户名是一个自然的选择。

然后,要验证给定的密码,您可以执行以下操作:
select 'OK' from loginDetails where ... and passwordHash = SHA1(CONCAT( passwordHashSalt, ?1 )) ,其中 ?1是要验证的密码。

有关更多信息,请在 Internet 上搜索“密码散列”,例如参见 herehere .

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


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!