У меня есть две функции, encrypt
и decrypt
. В encrypt
я создаю ключ, шифрую строку и добавляю в начало строки сам ключ. В decrypt
сначала отделяю ключ от зашифрованной строки(размер ключа фиксированный) и пытаюсь расшифровать, при этом результат не совпадает с начальной строкой, что и является проблемой.
Проверил в дебаге, массив key
при вызове decrypt(encrypt(string))
в обеих функциях одинаковый, видимо проблема в SecretKeySpec
(имхо).
Как можно исправить?
Сам код:
static String encrypt(String str) {
SecretKeySpec sks = null;
byte[] key = null;
try {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed("this is seed".getBytes());
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128, sr);
key = kg.generateKey().getEncoded();
sks = new SecretKeySpec(key, "AES");
} catch (Exception e) {
Log.e("Crypto", "AES secret key spec error");
}
// Encode the original data with AES
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, sks);
encodedBytes = c.doFinal(str.getBytes());
} catch (Exception e) {
Log.e("Crypto", "AES encryption error");
}
return Base64.encodeToString(key, Base64.DEFAULT) +
Base64.encodeToString(encodedBytes, Base64.DEFAULT);
}
static String decrypt(String str) {
byte[] key = Base64.decode(str.substring(0, 25), Base64.DEFAULT);
byte[] strBytes =
Base64.decode(str.substring(25, str.length()), Base64.DEFAULT);
SecretKeySpec sks = new SecretKeySpec(key, "AES");
// Decode the encoded data with AES
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, sks);
decodedBytes = c.doFinal(strBytes);
} catch (Exception e) {
Log.e("Crypto", "AES decryption error");
}
return Base64.encodeToString(decodedBytes, Base64.DEFAULT);
}
UPD Вызов методов:
editText.setText(Crypt.encrypt(editText.getText().toString()));
...
editText.setText(Crypt.decrypt(editText.getText().toString()));
Проблема у вас в не в ключе, а в лишнем кодировании при возврате строки.
Проще всего такой код отлаживать на JVM при помощи тестов.
// этот тест для обычного JUnit
// я не пробовал запускать его на андроиде
@Test
public void encrypt() throws Exception {
String cryptoText = AES.encrypt("test");
String plainText = AES.decrypt(cryptoText);
assertThat(plainText, is("test"));
}
static String encrypt(String str) {
SecretKeySpec sks = null;
byte[] key = null;
try {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed("this is seed".getBytes());
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128, sr);
key = kg.generateKey().getEncoded();
sks = new SecretKeySpec(key, "AES");
} catch (Exception e) {
Log.e("Crypto", "AES secret key spec error");
}
// Encode the original data with AES
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, sks);
encodedBytes = c.doFinal(str.getBytes());
} catch (Exception e) {
Log.e("Crypto", "AES encryption error");
}
// я добавил длину ключа и разделитель
String encodeKey = Base64.encodeToString(key, Base64.DEFAULT);
return encodeKey.length() + "$" + encodeKey +
Base64.encodeToString(encodedBytes, Base64.DEFAULT);
}
static String decrypt(String str) {
int pos = str.indexOf("$");
int keyLength = Integer.valueOf(str.substring(0, pos));
int keyStart = pos + 1;
byte[] key = Base64.decode(str.substring(keyStart, keyStart + keyLength), Base64.DEFAULT);
int dataStart = keyStart + keyLength;
byte[] strBytes =
Base64.decode(str.substring(dataStart, str.length()), Base64.DEFAULT);
SecretKeySpec sks = new SecretKeySpec(key, "AES");
// Decode the encoded data with AES
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, sks);
decodedBytes = c.doFinal(strBytes);
} catch (Exception e) {
Log.e("Crypto", "AES decryption error");
}
// Base64 не надо, так как у вас там просто строка
// return Base64.encodeToString(decodedBytes, Base64.DEFAULT);
return new String(decodedBytes);
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
Чем отличаются между собой метод по умолчанию, объявленный в интерфейсе с модификатором default и обычный метод, объявленный в обычном классе?
Полазив в anroid studio я нашел файлы векторной графики в (данном случаи это были иконки, в форматеxml)
я тут начал писать программу в javafx и у меня скопилось много вопросов по поводу координат в инете я нечего не нашел