7

Field LoginId と Password を使用してエンティティ クラスを作成しました。

パスワードを暗号化し、AES_ENCRYPT を使用してデータベースに保管しています。

復号化されたパスワードのみを取得したい。そのため、NAtiveQueryis を使用して AES_DECRYPT を使用するのは、OPen JPA 2.0 です。

私が書いたクエリは次のとおりです。

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

リクエストを処理するクエリとエラーの間違いを教えてください。

4

1 に答える 1

9

類似の質問: "[B" はどのような Java 型ですか?

MySQLは を返すのでAES_DECRYPTなく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で、検証するパスワードです。

詳細については、インターネットで「パスワード ハッシュ」を検索してください。たとえば、こちらまたはこちらを参照してください。

これらのハッシュ操作は、必要に応じて、代わりにデータベース クライアント コードで実行することもできます。

于 2012-12-24T14:50:49.663 に答える