Отправка сообщений между двумя клиентами, как проверить личность отправителя? - PullRequest
1 голос
/ 03 ноября 2010

Итак, предположим, что у вас есть два клиента, 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):

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

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

Ответы [ 4 ]

2 голосов
/ 03 ноября 2010

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

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

Для 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

0 голосов
/ 03 ноября 2010

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

Допустим, у вас есть 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. Вы захотите использовать встроенные методы для подписи сообщения.Пусть Framework делает хеширование / etc

0 голосов
/ 03 ноября 2010

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

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

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

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

0 голосов
/ 03 ноября 2010

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

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

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

...