使用中のパスワードのアルゴリズム#DelegatingPasswordEncoderの変更方法
16942 ワード
DelegatingPasswordEncoder
春はDelegatingPasswordEncoder彼はとても善良なやつで、いろいろなアルゴリズムを同時に使うことができます.
まさか、
Specification
このクラスのconstructorは以下の通りです.
Stringを追加する必要があります.次のidToPasswordEncoderで使用するキーを使用できます.以下の例を詳しく見ると分かります.
(2) idToPasswordEncoder Mapkey:アルゴリズムごとのプレフィックスを表す value:このアルゴリズムの実装体 例
DelegatingPasswordEncoderのソースコードから見ると:ここPREFIXは「{」、SUFFIXは「}」 低互換性
最初からDelegatingPasswordEncoderを使わなかったらどうなりますか?
現在のDBの値にprefixがないため、クラスは対応できません.
ただし、この場合に対応するため、
Encodeのアップグレード
インタフェースPasswordEncoderは、UpgradeEncodeによって、対応するパスワードをアップグレードする必要があるかどうかを判断します.
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder#upgradeEncoding
BCCRyptPasswordEncoderは強度を指定し、この強度より低いパスワードを受信したときにtrueを返すことができます.
DelegatingPasswordEncoder.upgradeEncoding()
この方法では、DelegatingPasswordEncoderを使用する場合にも、次の操作を実行できます.
すなわち,上記コードの目的は,デバッガアルゴリズムを用いない暗号文をデバッガアルゴリズムのコードに変換することといえる.
春はDelegatingPasswordEncoder彼はとても善良なやつで、いろいろなアルゴリズムを同時に使うことができます.
まさか、
{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
{noop}password
{pbkdf2}5d923b44a6d129f3ddf3e3c8d29412723dcbde72445e8ef6bf3b508fbf17fa4ed4d6b99ca763d8dc
{scrypt}$e0801$8bWJaSu2IKSn9Z9kM+TPXfOc/9bdYSrN1oD9qfVThWEwdRTnO7re7Ei+fUZRJ68k9lTyuTeUp4of4g24hHnazw==$OAOec05+bXxvuu/1qZ6NUR+xQYvYv7BeL1QxwRpY5Pc=
{sha256}97cde38028ad898ebc02e690819fa220e88c62e0699403e94fff291cfffaf8410849f27605abcbc0
このように保存された暗号文にprefixを付けてアルゴリズムを区別する方法.Specification
このクラスのconstructorは以下の通りです.
public DelegatingPasswordEncoder(
String idForEncode, // (1)
Map<String, PasswordEncoder> idToPasswordEncoder // (2)
)
(1)idForEncode暗号文を生成する際に使用するアルゴリズムを指定する必要がある.つまり、これはデフォルトのアルゴリズムと同じです.Stringを追加する必要があります.次のidToPasswordEncoderで使用するキーを使用できます.以下の例を詳しく見ると分かります.
(2) idToPasswordEncoder Map
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
import org.springframework.security.crypto.password.DelegatingPasswordEncoder
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder
val encoder = DelegatingPasswordEncoder(
"bcrypt",
mapOf(
"bcrypt" to BCryptPasswordEncoder(),
"scrypt" to SCryptPasswordEncoder(),
"pbkdf2" to Pbkdf2PasswordEncoder()
)
)
val encrypted = encoder.encode("password") // (1)
encoder.matches("password", encrypted) shouldBe true
(1)idForEncodeは"bcrypt"
で、encodeを呼び出す際に使用するBCryptPasswordEncoder()
符号化する.dbには、次のものが含まれます.{bcrypt}$2a$10$dXJ3SW6G7P50lGmMkkmwe.20cQQubK3.HZWzG3YB1tlRy.fqvM/BG
同じ結果を残す.DelegatingPasswordEncoderのソースコードから見ると:
@Override
public String encode(CharSequence rawPassword) {
return PREFIX + this.idForEncode + SUFFIX + this.passwordEncoderForEncode.encode(rawPassword);
}
this.passwordEncoderForEncode
とidToPasswordEncoder.get(idForEncode)
同じ最初からDelegatingPasswordEncoderを使わなかったらどうなりますか?
現在のDBの値にprefixがないため、クラスは対応できません.
ただし、この場合に対応するため、
defaultPasswordEncoderForMatches
を指定することができる.val encoder = DelegatingPasswordEncoder(
"bcrypt",
mapOf(
"bcrypt" to BCryptPasswordEncoder(),
"scrypt" to SCryptPasswordEncoder(),
"pbkdf2" to Pbkdf2PasswordEncoder()
)
)
encoder.setDefaultPasswordEncoderForMatches(BCryptPasswordEncoder())
これにより,接頭辞のない暗号化ゲートが入ってくると,BCryptPasswordEncoder
を用いて符号化を試みる.defaultPasswordEncoderForMatches
指定されていない場合、接頭辞のないパスワードゲートが入るとEllegalArgumentExceptionが発生するEncodeのアップグレード
インタフェースPasswordEncoderは、UpgradeEncodeによって、対応するパスワードをアップグレードする必要があるかどうかを判断します.
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder#upgradeEncoding
@Override
public boolean upgradeEncoding(String encodedPassword) {
if (encodedPassword == null || encodedPassword.length() == 0) {
this.logger.warn("Empty encoded password");
return false;
}
Matcher matcher = this.BCRYPT_PATTERN.matcher(encodedPassword);
if (!matcher.matches()) {
throw new IllegalArgumentException("Encoded password does not look like BCrypt: " + encodedPassword);
}
int strength = Integer.parseInt(matcher.group(2));
return strength < this.strength;
}
BCryptPasswordEncoderのソースコードを参照してください.BCCRyptPasswordEncoderは強度を指定し、この強度より低いパスワードを受信したときにtrueを返すことができます.
DelegatingPasswordEncoder.upgradeEncoding()
この方法では、DelegatingPasswordEncoderを使用する場合にも、次の操作を実行できます.
@Compo
class PasswordChecker(
private val passwordUpdater: PasswordUpdater
) {
private val encoder = DelegatingPasswordEncoder(
"bcrypt",
mapOf(
"bcrypt" to BCryptPasswordEncoder(),
"scrypt" to SCryptPasswordEncoder()
)
).also {
it.setDefaultPasswordEncoderForMatches(BCryptPasswordEncoder())
}
fun passwordConfirm(userId: Long, rawPassword: String, encryptedPassword: String): Boolean {
if (!encoder.matches(rawPassword, encryptedPassword)) return false
if (encoder.upgradeEncoding(encryptedPassword)) {
val newPassword = encoder.encode(rawPassword)
passwordUpdater.update(userId, newPassword)
}
return true
}
}
DelegatingPasswordEncoder.upgradeEncodeは、パスワード文がidForEncodeを使用していない場合(すなわち、ポーリングアルゴリズムを使用していない場合)にtrueを放出します.すなわち,上記コードの目的は,デバッガアルゴリズムを用いない暗号文をデバッガアルゴリズムのコードに変換することといえる.
Reference
この問題について(使用中のパスワードのアルゴリズム#DelegatingPasswordEncoderの変更方法), 我々は、より多くの情報をここで見つけました https://velog.io/@hanqyu/사용-중인-비밀번호의-알고리즘을-바꾸는-방법-DelegatingPasswordEncoderテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol