2015-06-15 2 views
0

Я пытаюсь зашифровать некоторый текст (здесь он называется кодом) и расшифровать его снова. Для этого я использую 4-значный Pin, который солен.Андроид шифрования и дешифрования текста не работает

После этого текст зашифрован, а также снова некоторое декодирование Base64, поэтому я могу безопасно выводить строку снова.

Как я понимаю, мне нужно выполнить base64.decode, а затем снова расшифровать его.

Но я не получил правильно зашифрованный текст. Просто какой-то другой текст. (что-то вроде этого [B @ 3ceB ...)

Это всего лишь маленький проект, ничего серьезного. Также это мое второе приложение для Android, поэтому некоторые хорошие примеры будут замечательными.

String pinstr = new String(); 
pinstr = "5555"; 
try { 
    EncryptDecrypt encryptor = new EncryptDecrypt(pinstr); 
    //encryptor.encrypt(code); 
    String encrypted = new String(); 
    encrypted = encryptor.encrypt(code); 

    String decrypted = new String(); 
    decrypted = encryptor.decrypt(encrypted); 

    Toast.makeText(MainActivity.this, decrypted, Toast.LENGTH_SHORT).show(); 
} catch (InvalidKeyException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (NoSuchAlgorithmException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (UnsupportedEncodingException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (NoSuchPaddingException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (IllegalBlockSizeException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} catch (BadPaddingException e) { 
    // TODO Auto-generated catch block 
    e.printStackTrace(); 
} 
public class EncryptDecrypt { 
    private SecretKeySpec skeySpec; 
    private Cipher cipher, cipher2; 


    EncryptDecrypt(String password) throws NoSuchAlgorithmException, 
    UnsupportedEncodingException, NoSuchPaddingException, 
    IllegalBlockSizeException, BadPaddingException, InvalidKeyException { 
     MessageDigest sha = MessageDigest.getInstance("SHA-1"); 
     byte[] key = Arrays.copyOf(sha.digest(("ThisisMySalt1234" + password).getBytes("UTF-8")), 
     16); 
     skeySpec = new SecretKeySpec(key, "AES"); 
     cipher = Cipher.getInstance("AES"); 
     cipher2 = Cipher.getInstance("AES"); 
    } 

    String encrypt(String clear) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException { 
     String encrypted = new String(); 

     cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 

     byte[] encryptedBytes = null; 
     encryptedBytes = cipher.doFinal(clear.getBytes()); 

     encrypted = Base64.encodeToString(encryptedBytes, Base64.DEFAULT); 

     return encrypted; 
    } 

    // fehlerhaft 
    String decrypt(String encryptedBase64) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException { 
     String decrypted = new String(); 
     cipher2.init(Cipher.DECRYPT_MODE, skeySpec); 
     byte[] decodedBytes = null; 


     decodedBytes = Base64.decode(encryptedBase64, Base64.DEFAULT); 

     decrypted = cipher2.doFinal(decodedBytes).toString(); 

     return decrypted; 

    } 
} 
+0

Похоже, что вам не хватает некоторых шагов. Эта страница должна помочь вам: https://www.owasp.org/index.php/Using_the_Java_Cryptographic_Extensions – ChrisStillwell

ответ

1

Тип вывода Cipher#doFinal(byte[]) является byte[], но Массивы не путь по умолчанию, в котором печатаются их содержание. Вызывая byte[].toString() на массиве, вы просто печатаете его тип и хэш-код. (Подробнее об этом here)

То, что вы хотите это

decrypted = new String(cipher2.doFinal(decodedBytes), "UTF-8"); 

, который говорит String конструктор, заданный массив содержит символы, которые закодированы в UTF-8.

Когда вы сделаете это, то вы также должны получить массив байтов из строки в определенной кодировке:

clear.getBytes("UTF-8") 

Если опустить кодировку, то используется в системе по умолчанию, которые могут сделать ваш plaintexts unrecoverable, когда вы отправляете зашифрованные тексты в системах, которые имеют разные системные кодировки по умолчанию.

Btw, вам не нужны как Cipher экземпляры. Достаточно только одного, так как вы инициируете его всегда при шифровании и расшифровке.


Другие проблемы безопасности:

  • Всегда использовать полностью квалифицированный шифр строку. Так что измените Cipher.getInstance("AES") на Cipher.getInstance("AES/CBC/PKCS5Padding").
  • Никогда не используйте режим ECB, который используется по умолчанию при использовании строки шифрования "AES". Это не семантически безопасно. Используйте по крайней мере, CBC режима со случайным IV:

    SecureRandom r = new SecureRandom(); 
    byte[] iv = new byte[16]; 
    r.nextBytes(iv); 
    ... 
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(iv)); 
    

    ХВ не должны быть секретом, так что вы можете просто приписать его к шифротексту и сращивать его перед расшифровкой.

  • Аутентификация вашего зашифрованного текста, чтобы вы не были уязвимы для атаки оскорбления дополнений и всегда можете проверить свои зашифрованные тексты на предмет целостности. Это можно легко сделать с помощью схемы шифрования-затем-MAC с сильным алгоритмом MAC, например HMAC-SHA256. Вы также можете использовать аутентифицированный режим шифрования, такой как GCM или EAX.

1

Ваш код работает, но вы выбрасываете результат.

Изменения линия

decrypted = cipher2.doFinal(decodedBytes).toString(); 

в

decrypted = new String(cipher2.doFinal(decodedBytes),"UTF-8"); 

Тогда вы получаете декодированную строку вместо идентификатора массива байт (вызов ToString() не даст вам массив байт в виде строки).

BTW: Вам не нужно инициализировать переменные в Java. String encrypted = new String(); бесполезен. Просто напишите String encrypted;.

Смежные вопросы