Отправка сообщений между двумя клиентами, как проверить личность отправителя?

StackOverflow https://stackoverflow.com/questions/4086993

Вопрос

Полагаю, что у вас есть два клиента, C1 и C2, каждый клиент имеет GUID, связанный с ним.

Как вы, когда вы получаете сообщение на C2, что предположительно исходит из C1 (проверяя GUID и видишь, что он соответствует GUID C1), но поскольку сообщение не гарантировано, что из C1 (C3 может просто отправить сообщение, отправку GUID C1 в заголовке сообщений) Должен быть некоторая проверка, что сообщение фактически произошло из C1.

Я искал использовать асимметричное шифрование (RSA), чтобы C1 отправить сообщение, которое состоит из [C1.GUID; RSAEncrypt(C2.PUBLIC_KEY, C1.GUID); MESSAGE], а затем позвольте C2 в основном сделать чек, как это (Python Pseudo Code):

message.GUID == RSADecrypt(C2.PRIVATE_KEY, message.ENCRYPTED_GUID)

Это жизнеспособный подход? Или есть ли другой умный / более очевидный способ проверить отправителя сообщения?

Это было полезно?

Решение

Ассимметричные алгоритмы были изобретены для таких целей, вот как работают цифровые подписи.

Однако у вашего подхода есть некоторые проблемы. Любой, кто с открытым ключом получателя может подделать подпись. Кроме того, подпись вообще не меняется! Любой, кто перехватывает сообщения, могут подделать быть действительным отправителем. Цель ассиметического шифрования - победить эти проблемы с ключевыми биржами, есть концепция цифровой подписи, которая в основном является ассиметрически зашифрованным хэш-хедом сообщения, которое вы бросаете.

Для RSA вам нужно сделать немного больше, чтобы создать цифровую подпись из основного алгоритма, см. Википедию для более подробной информации: http://en.wikipedia.org/wiki/rsa#signing_messages.

Я просто использовал алгоритм цифровой подписи из библиотеки. Первый поиск Google появляется с этим для Python:

http://www.example-code.com/python/pythonrsa.asp.

http://www.chilkatsoft.com/dsa-python.asp.

Другие советы

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

[ClientName; RSA-ENCRYPTED(GUID+Timestamp); MESSAGE]

В этом методе шифрование RSA будет выполнено с использованием открытого ключа Client2, чтобы только закрытый ключ Client2 может разблокировать его. Используя клиентское значение, Client2 может извлечь ожидаемый GUID от DataSource, а затем сопоставить возвращенный GUID против одного в шифровании. Я включил использование временного камня в качестве соли, так что зашифрованная строка выходит по-разному каждый раз. Он считается очень слабым для использования временной темы в качестве рандомизации для соли, но она получает точку. Другие более безопасные / случайные алгоритмы могут быть реализованы.

Любой, кто поднимает сообщения между клиентом и сервером, сможет подводить новые сообщения, имеет клиента GUID Никогда не меняйте, ни RSA-ENCRYPTED-GUID.

Рассмотрите возможность переключения на эту модель сообщения: [GUID; ENCRYPTED_CONTENT_CHECKSUM; CONTENT].

Checksum(message.CONTENT) == 
    RSADescrypt(C1.PUBLIC_KEY, message.ENCRYPTED_CONTENT_CHECKSUM)

Тем не менее, любой, кто следует повторно отправлять сообщения.

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

Позвольте сказать, у вас есть 3 компьютера

Comp1 Comp2 Comp3.

Также скажу, что вы хотите, чтобы Comp1 отправить сообщение для Comp3. Вам все равно, если сообщение было перехвачено, но вы заботитесь о том, что он не подделал.

Comp1 будет иметь цифровой подписать сообщение с его закрытым ключом

Comp2 перехватит сообщение от Comp1 на Comp3, но не может изменить сообщение, не принудив подпись

Comp2 будет передавать сообщение на Comp3

Comp3 будет использовать открытый ключ Comp1 для расшифровки подписи и использовать хэш в подписи для проверки содержимого.

Теперь, если вы хотите зашифровать данные, вам нужно добавить дополнительный шаг

Comp1 будет иметь цифровой подписать сообщение с его закрытым ключом

Comp1 будет генерировать ключ случайных шифров (обычно AES) и шифрует сообщение.

Comp1 примет этот ключ шифрования и шифрует его с открытым ключом Comp3

Comp2 перехватит сообщение, но не может прочитать его без закрытого ключа Comp3

Comp2 будет передавать сообщение на Comp3

Comp3 будет использовать его закрытый ключ для расшифровки ключа AES

Comp3 расшифрует все сообщения, используя клавишу AES

Comp3 проведет сообщение, расшифровывая подпись с открытым ключом Comp1.

Подпись содержит хэш сообщения, если хеш и хеш-матча сообщения, то данные не повреждены.

Вы можете включить GUID в полезной нагрузке в качестве поиска, чтобы решить, какие открытые ключи использовать.

PS Вы захотите использовать встроенные методы, чтобы подписать сообщение. Пусть каркас делает хеширование / и т. Д.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top