今回は通信(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) {
}
はい.じゃあ繋げてみよう.手順としてはこう.
- JSchインスタンスの生成.
- 鍵の登録
- セッションの取得
- ChannelSftpインスタンスの生成
- セッションの取得
- やりたい処理
- 後処理
サンプルコードはこんな感じかな.
/********* 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で通信設計したほうが安全なのかな?
ラベル: pm, pm4a