Skip to content

Instantly share code, notes, and snippets.

@k-ohkura
Last active October 6, 2017 14:45
Show Gist options
  • Save k-ohkura/fc346c6a854a2d505fb0b5cfbd2c4612 to your computer and use it in GitHub Desktop.
Save k-ohkura/fc346c6a854a2d505fb0b5cfbd2c4612 to your computer and use it in GitHub Desktop.
package jp.kogane.dev.prv.securitytester;
import android.content.Context;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class EncryptionUtil {
private static final int KEY_LENGTH = 256; // bits
private static final String RANDOM_KEY_FILE_NAME = "key.piece"; // Change me if needed
private static final byte[] HARD_CODED_KEY;
private static final String AES_ALGORITHM = "AES";
static {
try {
// Change me
// KEY_LENGTHより短いbit数になるようにする(eg. ASCII 16文字の場合 16 bytes * 8 で128 bits)
HARD_CODED_KEY = "0123456789abcdef".getBytes("US-ASCII");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Unsupported Encoding");
}
}
/** ハードコーディングされた鍵とアプリごとにランダム生成した鍵を組み合わせた合体鍵を作り、返すメソッド. */
public static byte[] getHybridKey(Context context) {
byte[] key = new byte[KEY_LENGTH / 8];
byte[] storedRandomKey;
String keyFilePath = context.getFilesDir().getPath() + File.separator + RANDOM_KEY_FILE_NAME;
if (new File(keyFilePath).exists()) {
// すでにランダム生成鍵をファイル保存済みのときは読み込むだけ
try {
FileInputStream in = context.openFileInput(RANDOM_KEY_FILE_NAME);
storedRandomKey = new byte[in.available()];
in.read(storedRandomKey);
} catch (IOException e) {
throw new RuntimeException("Could't restore password.");
}
} else {
// 初回
try {
// ハードコーディング分を引いた残りの鍵をランダム生成する
storedRandomKey = createRandomPassword((KEY_LENGTH / 8) - HARD_CODED_KEY.length);
FileOutputStream out = context.openFileOutput(RANDOM_KEY_FILE_NAME, Context.MODE_PRIVATE);
out.write(storedRandomKey);
out.flush();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("Could't store password.");
}
}
// 鍵を合体させる
int cursor;
for (cursor = 0; cursor < HARD_CODED_KEY.length; cursor++) {
key[cursor] = HARD_CODED_KEY[cursor];
}
for (int i = 0; cursor < key.length; cursor++) {
key[cursor] = storedRandomKey[i++];
}
return key;
}
public static byte[] createRandomPassword(int length) {
byte[] key = new byte[length];
new SecureRandom().nextBytes(key);
return key;
}
public static byte[] encryptByAES(byte[] bytes, SecretKeySpec secKey) {
try {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secKey);
return cipher.doFinal(bytes);
} catch (GeneralSecurityException e) {
e.printStackTrace();
throw new RuntimeException("Encryption failed.");
}
}
public static byte[] decryptByAES(byte[] bytes, SecretKeySpec secKey) {
try {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secKey);
return cipher.doFinal(bytes);
} catch (GeneralSecurityException e) {
e.printStackTrace();
throw new RuntimeException("Decryption failed.");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment