私は認証のためのパスワードが必要な場合があります。
この「パスワード」はホストによって選択され、別のチャネル(WhatsAppなど)を介して「クライアント」に伝えられるため、このアプリケーションは機密データを処理しません。 したがって、クライアントが認証を行いたい場合、ホストはクライアントに送信されるランダムなStringを生成します。
クライアントは、ユーザが入力したパスワードでこのランダム文字列を暗号化します。
暗号化されたランダムな文字列は、ホストに送信されます。
ホストは、この暗号化された文字列を同じパスワードによって生成されたキーで復号化します。
暗号化されていないと、元の文字列が一致する場合、ユーザーがログインしている
これは私がこれまでに思い付いたものです:。パスワードのみに基づいてAESキーを生成
String base64;
char[] password = "password".toCharArray();
String randomString = new BigInteger(130, new SecureRandom()).toString(32);
try {
//Encrypt Client Side
SecretKey key = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512").generateSecret(new PBEKeySpec(password)).getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, key);
base64 = Base64.getEncoder().encodeToString(cipher.doFinal(randomString.getBytes(StandardCharsets.UTF_8)));
} catch (GeneralSecurityException e) {
throw new IllegalStateException(e);
}
try {
//Decrypt Server Side
SecretKey key = new SecretKeySpec(SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512").generateSecret(new PBEKeySpec(password)).getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key);
//Check if both strings match
System.out.println(Arrays.equals(cipher.doFinal(Base64.getDecoder().decode(base64)), randomString.getBytes(StandardCharsets.UTF_8)));
} catch (GeneralSecurityException e) {
throw new IllegalStateException(e);
}
は、残念ながら、このコードは例外をスロー:java.security.spec.InvalidKeySpecException: Salt not found
私は別のを使用すべきアルゴリズムを使用するか、パスワード自体をハッシュするか、まったく別の方法で塩を生成する必要がありますか? ランダムな文字列とともに生成された塩を送る必要がないようにしたい