« Teeda | Main | JFormattedTextField »

2007.04.12

Subversion認証情報の保存

 SubversionでBasic認証を要求されるリポジトリへアクセスした場合、認証情報を保存することができますが、その際のパスワードの保存の仕方に関して。

 使用するクライアントによって、平文で保管されたり、wincrypt形式で保存されたり(Windowsの場合)。JavaHLで、DLL経由で処理した場合は自動的にwincrypt形式になるようですが、SVNKitを用いた場合、当然のことながらwincryptを使用することができず、そのままでは平文で保存されてしまいます(参考資料)

 それに代わる方法として、SVNKitではorg.tmatesoft.svn.core.internal.wc.SVNPasswordCipherを継承したクラスを作成することにより、任意の方式で暗号化処理を行うことができるようになっています。もっとも、独自の方法で暗号化すると、他のクライアントでアクセスしたときに復号化に失敗して、再度認証を要求してくるようになったりしますが(^^;

 例えば、こんな感じ。暗号化のキーを固定していますが、そこはサンプルと言うことで(笑)。AESを用いて暗号化処理を行うようにしています。

public class SVNCustomPasswordCipher extends SVNPasswordCipher {
 private static final String KEY = "svncustomencrypt";
 public SVNCustomPasswordCipher(String name) {
  super();
  super.registerCipher(name, this);
 }
 @Override
 public String decrypt(String encryptedData) {
  if (encryptedData == null) return null;
  try {
   SecretKeySpec sksSpec = new SecretKeySpec(KEY.getBytes(), "AES");
   Cipher cipher = javax.crypto.Cipher.getInstance("AES");
   cipher.init(javax.crypto.Cipher.DECRYPT_MODE, sksSpec);
   byte[] decrypted = cipher.doFinal(StringUtils.parseHexString(encryptedData));
   return new String(decrypted);
  } catch (Exception e) {
   return encryptedData;
  }
 }
 @Override
 public String encrypt(String rawData) {
  if (rawData == null) return null;
  try {
   SecretKeySpec sksSpec = new SecretKeySpec(KEY.getBytes(), "AES");
   Cipher cipher = Cipher.getInstance("AES");
   cipher.init(Cipher.ENCRYPT_MODE, sksSpec);
   byte[] encrypted = cipher.doFinal(rawData.getBytes());
   return StringUtils.createHexString(encrypted);
  } catch (Exception e) {
   return rawData;
  }
 }
}

で、これを使うようにする場合、

new SVNCustomPasswordCipher("custom");
SVNPasswordCipher.setDefaultCipherType("custom");

って感じで登録処理を行います。複数の暗号化方式を登録することも可能となっていますが、

  • 復号化するときは、ファイルに保存されているpasstypeを元にCipherクラスを選択されます。
  • 暗号化するときは無条件でDefaultCipherTypeを使用されます。
  • DefaultCipherTypeが指定されていない場合、HashMapのキーの並び順で先頭のものがDefaultCipherTypeとして登録されます。

    という動きをします。なので、1つしか登録しない場合は、setDefaultCipherTypeの指定はなくても(おそらく期待通りに)動きますが、複数を登録する場合は明示的にDefaultCipherTypeを指定しておかなければ、予期しないCipherクラスを用いてパスワードのストアを行う可能性があります。

  • |

    « Teeda | Main | JFormattedTextField »

    Java」カテゴリの記事

    Subversion・Trac・etc.」カテゴリの記事

    Comments

    Post a comment



    (Not displayed with comment.)


    Comments are moderated, and will not appear on this weblog until the author has approved them.



    TrackBack


    Listed below are links to weblogs that reference Subversion認証情報の保存:

    « Teeda | Main | JFormattedTextField »