FieldLoginIdとPasswordを使用してエンティティクラスを作成しました。
Iamはpasswrdを暗号化し、AES_ENCRYPTを使用してデータベースに保存します。
復号化されたパスワードのみを取得したい。したがって、OPen JPA2.0でNAtiveQueryisを使用して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<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
クエリとリクエストを処理する際の間違いを教えてください。
同様の質問: どのようなJavaタイプは "[B"?
MySQLの_AES_DECRYPT
_はnotではなくString
を返しますが、「[B」で示されるバイトの配列を返します。結果を_byte[]
_にキャストし、そこから文字列を作成します。
パスワードを解読する必要さえないようです。 validateUser
したいだけですよね? -その場合、他の人が指摘しているように、安全なハッシュを使用する必要があります。
MySQLは、必要な 関数 :MD5(安全でないと見なされる)、SHA1(ほぼ標準)、およびSHA2(SHA1よりもさらに安全)をすでに提供しているため、これを簡単に行うことができます。
したがって、スキームは基本的に次のようになります。
insert into loginDetails (..., passwordHashSalt, passwordHash) values ( ..., ?1, SHA1(CONCAT( ?1, ?2 )) )
、ここで_?1
_は一意の「salt」に設定されます。これはたとえばユーザー名自体であり、_?2
_は実際のパスワードです。ソルトもDBに保存する必要があり、「ユーザー/パスワードごとに一意である必要がある」ことに注意してください。したがって、ユーザー名はそのための自然な選択です。
次に、指定されたパスワードを確認するには、次の操作を実行できます。
select 'OK' from loginDetails where ... and passwordHash = SHA1(CONCAT( passwordHashSalt, ?1 ))
、ここで_?1
_は検証されるパスワードです。
詳細については、インターネットで「パスワードハッシュ」を検索してください。たとえば、 ここ または ここ を参照してください。
これらのハッシュ操作は、必要に応じて、代わりにデータベースクライアントコードで実行することもできます。