以前Androidで暗号化のための秘密鍵を(なるべく)安全に保持するという記事を書いたのですがサンプルコードを適当に書いて長らく放置していたので簡単ながらライブラリ化させてみました。
Cryptore
https://github.com/KazaKago/Cryptore
What's this?
Android Keystore Systemをbyte配列を暗号化することに特化させて使いやすくしたシンプルな補助ライブラリです。
Android Keystore System自体は安全な鍵生成のための仕組みなので暗号化以外にも様々な使い道がありますが、文字列暗号化のためだけにシンプルに使おうと思っても微妙にややこしかったり毎回割とテンプレート的なコードを書かなくてはならないのでその部分をラップしたものがこのライブラリになります。
MITライセンスにより配布しています
Requirement
- 暗号化方式:RSA
- Android 4.3 (API 18) 以降
- 暗号化方式:AES
- Android 6.0 (API 23) 以降
上記はAndroid Frameworkの仕様に依存します。ハードウェア条件も満たしているかご確認下さい。
詳しくは公式リファレンスを御覧ください。
Install
利用するモジュールのgradle.buildに以下を追記して下さい
dependencies {
compile 'com.kazakago.cryptore:cryptore:{LATEST_VERSION}'
}
How to use
初期化
Cryptore getCryptore(Context context, String alias) throws Exception {
Cryptore.Builder builder = new Cryptore.Builder(alias, CipherAlgorithm.RSA);
builder.setContext(context); //API Lv22以下では必要です。
// builder.setBlockMode(BlockMode.ECB); //必要に応じて変更して下さい
// builder.setEncryptionPadding(EncryptionPadding.RSA_PKCS1); //必要に応じて変更して下さい
return builder.build();
}
上記のサンプルではRSA暗号モードで初期化しています。
alias
がAndroid Keystore Systemから暗号化キーを取り出すための引換券の役割を果たしますので、暗号化復号化で同じものを指定して下さい。
またブロックモードやパディングは必要に応じて変更して下さい
Android Frameworkの仕様により、API Lv22以下で使用する場合はContext
が必要になるのでセットして下さい。
何も指定しないデフォルトでは以下の通りになります
-
暗号化方式:RSA
- ブロックモード:ECB
- パディング:PKCS1Padding
-
暗号化方式:AES
- ブロックモード:CBC
- パディング:PKCS7Padding
暗号化
文字列をbyte配列に変換した後、Cryptore#encryptメソッドに放り込むだけです。
このサンプルではその後Base64エンコード文字列化を行っています。
String encrypt(String plainStr) throws Exception {
byte[] plainByte = plainStr.getBytes();
EncryptResult result = getCryptore().encrypt(plainByte);
return Base64.encodeToString(result.getBytes(), Base64.DEFAULT);
}
AES暗号を用いる場合にはEncryptResult.cipherIVに初期値ベクトルが入っており、復号化時に必要となるのでそれもSharedPreferencesあたりで暗号化文字列と一緒に保存しておいて下さい。
復号化
暗号化された文字列をBase64デコードしてCryptore#decryptメソッドへ渡して下さい。
String decrypt(String encryptedStr) throws Exception {
byte[] encryptedByte = Base64.decode(encryptedStr, Base64.DEFAULT);
DecryptResult result = getCryptore().decrypt(encryptedByte, null);
return new String(result.getBytes());
}
AES暗号を用いる場合はCryptore#decryptの第2引数に暗号化時に保持したIVを渡して下さい。
Sample code
そんなに悩むところはないと思っていますが、JavaとKotlinで完全な動作を確認できるサンプルコードを含んでいます。
Important
Android Keystore Systemではアプリ内には秘密鍵を持っていないので他の端末にそのまま暗号化文字列を移動させても復号化できません。
Android MからデフォルトONになったAutoBackupや独自バックアップなどの仕組みに暗号化された文字列を含めないようにご注意下さいm(__)m