현재이 게시물에서 영감을 얻은 Android의 AES 256을 사용하여 대칭 암호화/복호화를 구현 중입니다. Java 256bit AES Encryption. 구현의 목적은 데이터베이스의 데이터를 암호화하는 것입니다. 나는 문자 [] 암호 소요 다음 생성자 사용 키 생성을 위해모든 메시지에 하나의 키와 임의의 IV를 사용하는 Android AES 비밀번호 기반 암호화
:
public Cryptography(char[] password) throws NoSuchAlgorithmException,
InvalidKeySpecException, NoSuchPaddingException {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
KeySpec spec = new PBEKeySpec(password, salt, 1024, 256);
secretKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
cipher = Cipher.getInstance(AES/CBC/PKCS5Padding);
}
내가 안드로이드 내 활동을 시작할 때 그래서 난 내 암호화 클래스의 새 인스턴스를 초기화하고 그러므로 생성 된 키를 얻을 수 . 소금은 16 바이트의 고정 된 임의의 바이트 []입니다. 그래서 나는 항상 같은 열쇠를 얻는다는 것을 의미합니다. 나중에 그 이유. 내가 한 활동에서 개체를 얻었다 후
지금 나는 다음과 같은 암호화를 사용하여 항상 같은 키 방식의 암호를 해독 할 수 있습니다 : 당신이 볼 수 있듯이
public byte[] encrypt(String cleartext) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException,
UnsupportedEncodingException, InvalidParameterSpecException {
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encText = cipher.doFinal(cleartext.getBytes(CHARSET_NAME));
byte[] iv = cipher.getParameters()
.getParameterSpec(IvParameterSpec.class).getIV();
byte[] enc = new byte[IV_SIZE + encText.length];
for (int i = 0; i < enc.length; i++) {
if (i < IV_SIZE)
enc[i] = iv[i];
else if (i < enc.length)
enc[i] = encText[i - IV_SIZE];
}
return enc;
}
public String decrypt(byte[] encryptedText) throws InvalidKeyException,
InvalidAlgorithmParameterException, UnsupportedEncodingException,
IllegalBlockSizeException, BadPaddingException {
byte[] iv = new byte[IV_SIZE];
byte[] dec = new byte[encryptedText.length - IV_SIZE];
for (int i = 0; i < encryptedText.length; i++) {
if (i < IV_SIZE)
iv[i] = encryptedText[i];
else if (i < encryptedText.length)
dec[i - IV_SIZE] = encryptedText[i];
}
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
return new String(cipher.doFinal(dec), CHARSET_NAME);
}
, 나는 암호문과 함께 신선한 새로운 IV를 저장을 매번 메시지를 암호화합니다.
결론 : 데이터베이스 테이블에서 하나의 암호화 키, 하나의 무작위 소금 및 모든 IV 필드를 사용합니다.
처음에는 데이터베이스 테이블에서 하나의 필드를 암호화하고 암호문과 함께 필요한 소금 및 IV 또는 적어도 하나의 테이블 행을 저장할 때마다 새 소금과 새 IV로 새 키를 생성하려고했습니다. 그러나 위에서 언급 한 이유는 Android 기기에서 키를 생성하는 데 많은 시간이 걸리기 때문입니다. 에뮬레이터에서 테스트했지만 키를 생성하는 데 약 2 초가 걸렸습니다. 이것이 Activity가 시작될 때 하나의 키를 생성 한 이유입니다.
마지막으로 내 질문 : 내 접근 방식으로, 하나의 키만 사용하여 충분히 안전하지만 모든 메시지에 대해 임의의 IV를 사용합니까? 현재 성능과 균형을 유지하여 가능한 한 안전하게 만들 수있는 또 다른 방법은 없습니다.
나는 그것이 내가 쓴 것과 누군가가 나에게 그것에 대한 조언을 줄 수 있기를 희망한다.
친절 감사
xoidberg