2011年8月8日月曜日

androidアプリ開発日記(2011/08/07)

今回は通信(SFTP)について.
ファイルをやり取りしようとしたら,まぁSFTPかなという感じを覚える.
ではAndroidアプリでSFTPはできるのだろうか?A.もちろんできる.

元はJDK用に開発されているJSchというライブラリを使用することで解決可能.
筆者が採用している認証方式は公開鍵暗号方式なので,
まずは鍵を生成する.
以下のような感じで.
File keyfile = new File("id_rsa");

final int type = KeyPair.RSA;
final String pass = "";
try {
 KeyPair keyPair = KeyPair.genKeyPair(jsch, type);
 keyPair.setPassphrase(pass);
 keyPair.writePrivateKey(keyfile.getAbsolutePath());
 keyPair.writePublicKey(keyfile.getAbsolutePath() + ".pub",
   <コメント>);
 keyPair.dispose();
} catch (JSchException e) {
} catch (FileNotFoundException e) {
} catch (IOException e) {
}

はい.じゃあ繋げてみよう.手順としてはこう.
  1. JSchインスタンスの生成.
  2. 鍵の登録
  3. セッションの取得
  4. ChannelSftpインスタンスの生成
  5. セッションの取得
  6. やりたい処理
  7. 後処理
サンプルコードはこんな感じかな.
/********* 1 *********/
JSch jsch = new JSch();
/*********************/
/********* 2 *********/
try {
 jsch.addIdentity("data/data/" + this.getPackageName()
   + "/files/id_rsa");
} catch (JSchException e) {
 return;
}
/*********************/
/********* 3 *********/
Session session = null;
try {
 session = jsch.getSession("takefumi", "netherworld.dip.jp", 22);
} catch (JSchException e) {
 return;
}
/*********************/
session.setUserInfo(new UserInfo() {
 @Override
 public void showMessage(String arg0) {
 }
 @Override
 public boolean promptYesNo(String arg0) {
  return true;
 }
 @Override
 public boolean promptPassword(String arg0) {
  return true;
 }
 @Override
 public boolean promptPassphrase(String arg0) {
  return true;
 }
 @Override
 public String getPassword() {
  return null;
 }
 @Override
 public String getPassphrase() {
  return "";
 }
});
/********* 4 *********/
try {
 session.connect();
} catch (JSchException e) {
 return;
}
/*********************/
/********* 5 *********/
ChannelSftp sftp = null;
try {
 sftp = (ChannelSftp) session.openChannel("sftp");
 sftp.connect();
} catch (JSchException e) {
 session.disconnect();
 return;
}
/*********************/
/********* 6 *********/
やりたい処理
/*********************/
/********* 7 *********/
sftp.disconnect();
session.disconnect();
/*********************/

最後に問題となるのが鍵の置き場所.見える場所に置いておけば置換が楽になるけど,
他のアプリからもアクセス可能になってしまうため少々危険.
かといってassetsやアプリ用の領域に置こうとすると,ファイルを置くための処理をアプリに実装せねばならないし,assetsの場合は取得できるのがInputStreamのみという素敵設計.
「じゃあ鍵を暗号化しちゃえばいいんでね?」という案も通らない.
JSchが鍵のファイルへのパスを要するからである.
うーん.androidではID+PASSで通信設計したほうが安全なのかな?

ラベル: ,

0 件のコメント:

コメントを投稿

登録 コメントの投稿 [Atom]

<< ホーム