Springセキュリティを使用するSpringプロジェクトがあります。私はSpring Boot 1.5を使用していましたが、Spring Boot 2.0に移行しました。
Spring Securityの最終リリースで Md5PasswordEncoder が削除されたことに気付きました。代わりにMd4PasswordEncoder
は、廃止された場合でも引き続き存在します( https://docs.spring.io/spring-security/site/docs/5.0.3.RELEASE/api/ )。
外部MD5エンコーダを使用する必要がありますか、それともクラスは別の場所に移動しますか?
_Md5PasswordEncoder
_が存在しなくなったという事実は、Spring Security 5が_MD5
_ハッシュを作成できないという意味ではありません。そのためにnew MessageDigestPasswordEncoder("MD5")
を使用します。
2つのオプションがあり、両方とも新しいDelegatingPasswordEncoder
で機能します。これは、_{MD5}password_hash
_のように、パスワードプレフィックスがハッシュアルゴリズムを決定することを想定しています。
Eitherデフォルトのパスワードエンコーダーを_MD5
_(大文字)に設定します。したがって、パスワードにプレフィックスが付いていない場合、デフォルトのエンコーダーが適用されます。
_PasswordEncoder passwordEncoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
passwordEncoder.setDefaultPasswordEncoderForMatches(new MessageDigestPasswordEncoder("MD5"));
_
またはデータベース内の既存のパスワードハッシュの前に_{MD5}
_を付けます。このようにして、DelegatingPasswordEncoder
は `MD5 'ハッシュにデリゲートします。何かのようなもの:
_update myusertable set pwd = '{MD5}' || pwd;
_
代わりにorg.springframework.security.crypto.password.PasswordEncoder
を使用する必要があります。 こちら は、新しいインターフェースへの切り替えに関する良い記事です。
MD5を使用する場合は、カスタマイズできます。
@Bean
public PasswordEncoder passwordEncoder() {
return new PasswordEncoder() {
@Override
public String encode(CharSequence charSequence) {
return getMd5(charSequence.toString());
}
@Override
public boolean matches(CharSequence charSequence, String s) {
return getMd5(charSequence.toString()).equals(s);
}
};
}
public static String getMd5(String input) {
try {
// Static getInstance method is called with hashing SHA
MessageDigest md = MessageDigest.getInstance("MD5");
// digest() method called
// to calculate message digest of an input
// and return array of byte
byte[] messageDigest = md.digest(input.getBytes());
// Convert byte array into signum representation
BigInteger no = new BigInteger(1, messageDigest);
// Convert message digest into hex value
String hashtext = no.toString(16);
while (hashtext.length() < 32) {
hashtext = "0" + hashtext;
}
return hashtext;
}
// For specifying wrong message digest algorithms
catch (NoSuchAlgorithmException e) {
System.out.println("Exception thrown"
+ " for incorrect algorithm: " + e);
return null;
}
}
もう安全ではないので、SpringはMD5を削除します。 Bcryptを使用する必要があります。
以下の私の解決策:
protected static String mergePasswordAndSalt(String password, Object salt, boolean strict) {
if (password == null) {
password = "";
}
if ((strict) && (salt != null) && ((salt.toString().lastIndexOf("{") != -1) || (salt.toString().lastIndexOf("}") != -1))) {
throw new IllegalArgumentException("Cannot use { or } in salt.toString()");
}
if ((salt == null) || ("".equals(salt))) {
return password;
}
return password + "{" + salt.toString() + "}";
}
public static String EncodingPassword(String password, String salt) {
String merge = mergePasswordAndSalt(password,salt,false);
return DigestUtils.md5Hex(merge);
}
上記の関数を使用して、以下のコードを置き換えます。
new Md5PasswordEncoder().encodePassword(String rawPass, Object salt);
Spring-security-core-3.1.4.RELEASE.jarのMd5PasswordEncoderのソースコードから、パスワードとソルトの処理方法を確認できます。
//org.springframework.security.authentication.encoding.BasePasswordEncoder.class
protected String mergePasswordAndSalt(String password, Object salt, boolean strict)
{
if (password == null) {
password = "";
}
if ((strict) && (salt != null) && (
(salt.toString().lastIndexOf("{") != -1) || (salt.toString().lastIndexOf("}") != -1))) {
throw new IllegalArgumentException("Cannot use { or } in salt.toString()");
}
if ((salt == null) || ("".equals(salt))) {
return password;
}
return password + "{" + salt.toString() + "}";
}