2014-02-12 7 views
3

Я использую этот метод шифрования для шифрования и дешифрования определенной строки: -Как проверить, зашифрована ли строка или нет?

package encryption; 

import java.security.Key; 

import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec; 

import sun.misc.BASE64Decoder; 
import sun.misc.BASE64Encoder; 

public class AES { 

    private static final String ALGO = "AES"; 
    private static final byte[] keyValue = 
     new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't', 
'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' }; 

public static String encrypt(String Data) throws Exception { 
     Key key = generateKey(); 
     Cipher c = Cipher.getInstance(ALGO); 
     c.init(Cipher.ENCRYPT_MODE, key); 
     byte[] encVal = c.doFinal(Data.getBytes()); 
     String encryptedValue = new BASE64Encoder().encode(encVal); 
     return encryptedValue; 
    } 

    public static String decrypt(String encryptedData) throws Exception { 
     Key key = generateKey(); 
     Cipher c = Cipher.getInstance(ALGO); 
     c.init(Cipher.DECRYPT_MODE, key); 
     byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData); 
     byte[] decValue = c.doFinal(decordedValue); 
     String decryptedValue = new String(decValue); 
     return decryptedValue; 
    } 
    private static Key generateKey() throws Exception { 
     Key key = new SecretKeySpec(keyValue, ALGO); 
     return key; 
} 

} 

Он отлично работает.

Проблема в том, что как я узнаю, что строка, которая должна быть расшифрована, зашифрована?

Я имею в виду, что могу передать длинную «незашифрованную» строку в метод дешифрования, и она все равно будет работать.

Любые предложения.

ответ

3

Нет окончательного способа рассказать; единственное, что вы можете сделать, это посмотреть на строку и посмотреть, похоже ли она на что-то понятное (грубо говоря, что-то, для чего file вернет нечто более конкретное, чем «данные»). Если у вас нет какой-либо характеристики, которую вы можете использовать для идентификации «простого текста» (возможно, все это ASCII или все кодовые точки Unicode для $ LANGUAGE), нет никакой неотъемлемой разницы между зашифрованным текстом и произвольными двоичными данными.

+0

В теории вы не можете, однако на практике вы можете делать такие вещи, как смотреть на разброс всех персонажей. В этом случае, поскольку они ожидают строку base64, это должно быть довольно легко. – placeybordeaux

+0

Отличное объяснение. Не так много людей получают, что зашифрованные данные в идеале должны быть такими же, как по-настоящему случайные данные. –

+0

@ PeterMichealLacey-Bordeaux Но что, если кто-то шифрует строку Base64? – chrylis

1

На этот вопрос нет идеальных ответов, так как нет 100% -ного уверенного способа узнать, что-то зашифровано. Однако он должен быть случайным образом распределен по всем возможным строкам base64, что означает, что он должен выглядеть намного иначе, чем обычный текст. Один из способов определить разницу между английскими и зашифрованными строками base64 - это увидеть, сколько пробелов есть.

В этом посте есть 92 пробела, но пространство символов не отображается в base64. Если вы имеете дело с вещами, отличными от обычного текста, это станет более интересным.

+0

Хотя нет уверенности в 100%, как вы заявляете, есть такой хороший шанс, что если вы действительно найдете способ обмануть его, вы бы сломали шифр ... сделав все это неактуальным. Мой ответ детализирует это решение. Статистический анализ менее совершенен. –

+0

Ах да, я не думал о обивке. – placeybordeaux

+0

Если бы это был ЕЦБ, я бы не подумал о хорошем способе сделать это, возможно, кроме добавления какого-то МАС и проверки его под независимым ключом. Но это добавит много сложности. –

3

Вы можете определить, если что-то зашифровано с помощью конкретной клавиши, алгоритма, режима и схемы дополнения, просто попытавшись ее расшифровать.

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

Одним из преимуществ режима CBC, который поддерживается практически в каждой широко используемой криптографической библиотеке, содержащей симметричные шифры (например, AES), является то, что каждый блок зависит от предыдущего с точки зрения его данных. Это означает, что ошибки будут распространяться, и вы, скорее всего, не сможете расшифровать данные, которые на самом деле не были зашифрованы или случайно были повреждены каким-то образом.

Я считаю, что это, вероятно, лучший удар для ваших строк кода, чтобы проверить, были ли данные переданы с помощью специального ключа, алгоритма, режима и схемы дополнений.

EDIT

Но, если вам нужно проверить с высокой достоверностью, что ключ является правильным, необходимо добавить код аутентификации сообщения (МАС) в конце вашего зашифрованного текста или текста.

Вы можете сформировать свое сообщение так:

CIPHERTEXT = ENCRYPT(KEY_1, PADDING, MODE, PLAINTEXT) 
MESSAGE = CIPHERTEXT || HMAC(KEY_2, CIPHERTEXT) 

CIPHERTEXT определяются как результат шифрования открытого текста под конкретным ключом, прокладки и режим работы

MESSAGE определяются как результат из CIPHERTEXT, имеющий результат HMAC, двоично-сцепленный (||).

KEY_1 является криптографически защищенным ключом, не зависящим от KEY_2, еще одним криптографически защищенным ключом.

Причина, по которой вы хотите вычислить HMAC против CIPHERTEXT, заключается в том, что вы не хотите, чтобы действительно выполнялось дешифрование, чтобы проверить, является ли сообщение законным.

Вам необходимо запустить зашифрованный сеанс, а затем обменять KEY_2 по этому зашифрованному каналу, что означает, что вы добавили накладные расходы на управление и сложность кода, но у вас есть 1/1^256 (по крайней мере) вероятность увидеть неправильное сообщение проходит через проверку HMAC.

После того, как вы подтвердите результат HMAC, вы можете быть уверены, что сообщение, вероятно, действительно зашифровано под KEY_1, при условии, что утечки не произошли с момента начала сеанса или времени жизни сообщения.

+0

Это полезно, но стоит отметить, что стандартная схема заполнения - [PKCS7/PKCS5 padding] (http://en.wikipedia.org/wiki/Padding_ (криптография) # PKCS7) - на самом деле не предназначена для обнаружения неправильный ключ. Например, если длина такова, что используется только один байт заполнения, то вероятность * неверного * ключа, передающего проверку заполнения, равна 1/256. Это может быть недостаточно для многих приложений. –

+0

@GregS Я пошел вперед и предложил альтернативу, которая охватывает вашу озабоченность. Я согласен, это немного фанки, чтобы попробовать и полагаться на заполнение, правильное. Это всего лишь один шаг в реальной проверке ошибок. Я бы определенно использовал в своих приложениях более сложную альтернативу. Но я предполагаю, что этот пользователь просто тестирует воды и не реализует производственное решение, поэтому мое первое объяснение было скорее ориентиром, чем рекомендацией. :) –

0

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

Обе стороны могут договориться о методе проверки правильности, например, CRC.

В отличие от ключа, который должен оставаться секретом, этот метод можно публично объявить.

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

Любая другая строка, отправленная для дешифрования, просто завершит проверку CRC.

BTW, метод аутентификации обычно является алгоритмом хеширования, таким как SHA, HMAC и т. Д. В силу своей природы, CRC обычно более уязвим для атак с выбранным шифротекстом, когда злонамеренная группа генерирует случайные строки, надеясь, что некоторые из они будут считаться подлинными.

+0

CRC не является криптографически защищенным и добавляет его к зашифрованному тексту, что приведет к утечке информации об открытом тексте. –

+0

Ну, я использовал CRC в качестве примера возможного метода аутентификации. Не сказал, что это безопасный вариант, и явно указал те, которые обычно используются для аутентификации. Я также добавил записку о CRC сразу после этого (хотя это могло произойти во время или сразу после вашей заметки). В любом случае, ваш проголосовательный голос крайне нежелателен в этом случае. Я не против брать их, когда я ошибаюсь, но в этом случае сам CRC не был основным моментом ответа !!! –

+0

Не беспокойтесь! Поскольку вы прояснили и объяснили выбранную уязвимость шифрованного текста, и я прокомментировал это, прежде чем вы внесли свое обновление, я отвлеку свое нижестоящее. - Вообще-то, я просто попытался сделать это, и он сказал, что он заблокирован. Если вы его отредактируете, я могу внести изменения. –

1

Конечно, возможно, если строка достаточно длинная. Those guys are detecting encrypted keys in memory dumps. Конечно, нет никакой гарантии 100% - простой contrexample, вы можете кодировать закодированную строку, поэтому ваш ввод выглядит уже как ключ.

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

Лучшая попытка - проанализировать, насколько случайным образом распределяются биты. Для BASE64 вы анализируете только 6 бит и т. Д.

+0

Это хороший момент. Вы можете фактически обнаружить последовательности, которые «выглядят случайными». Но простой криптографически безопасный генератор случайных чисел также может обмануть это. Он также не проверяет, шифруется ли строка под указанным ключом, что приведет к сбою в расшифровке в любом случае, поэтому обнаружение зашифрованных данных становится бессмысленным. +1 хотя. –

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