OpenLDAPとSpringでPBKDF2の実装が異なる
Published:
By nobCategory: Posts
前提
| software | version | 
|---|---|
| OpenLDAP | 2.6.3 | 
| Spring | 3.1.1 | 
| Spring Security | 6.1.1 | 
事象
slappasswdを使ってパスワードを作成してOpenLDAPに登録したのだがSpringのLDAP認証が通らない。
原因
OpenLDAPとSpring SecurityでPBKDF2の実装が異なる。
- 
       
OpenLDAP
 - 
       
Spring Security
 
OpenLDAPのpbkdf2モジュールでは Adapted base64 encode というコーデックを用いているらしい。
対策
Springにモジュールを追加する
PasswordEncoderを実装する。Springでjava.util.Base64を使用している処理を置き換える。
pw-pbkdf2.cの51行目から102行目 を参考にjava.util.Base64の出力を加工する。
class AdaptedBase64 {
  public static String encode(byte[] bytes) {
    log.trace("encoding bytes=%s", hex(bytes));
    String base64 = Base64.getEncoder().encodeToString(bytes);
    log.trace("base64=%s", base64);
    String adaptedBase64 = base64.substring(0, base64.indexOf("=")).replace("+", ".");
    log.trace("adaptedBase64=%s", adaptedBase64);
    return adaptedBase64;
  }
  public static byte[] decode(String text) {
    log.trace("decoding text=%s", text);
    String tmp = text.replace(".", "+");
    int paddingLength = 4 - (tmp.length() % 4);
    String base64 = tmp + "=".repeat(paddingLength);
    log.trace("base64=%s", base64);
    byte[] bytes = Base64.getDecoder().decode(base64);
    log.trace("decoded bytes=%s", hex(bytes));
    return bytes;
  }
}