То, что вы делаете, кажется разумным, за исключением того, что вы не проверяете параметры (что будет довольно большой проблемой).
Что-то, что очень похоже на ваш дизайн, которое было бы разумно скопировать, - это Схема аутентификации запросов Amazon Web Services
В частности, убедитесь, что ваша схема кодирования параметров является однозначной и обратимой; Amazon в какой-то момент облажался . Учитесь на своих ошибках. :)
Говоря криптографически, то, что вы делаете, называется не подписью, а скорее кодом аутентификации сообщения (MAC). MAC может быть создан и проверен любым, кто использует секретный ключ (термин «подпись» обычно зарезервирован для схем с открытым ключом, таких как DSA или RSA). MD5 (msg || K) - известный и разумно нормальный MAC; Я не уверен, что вы пропустили это случайно или намеренно, но метод, который на первый взгляд кажется эквивалентным, MD5 (K || msg), довольно небезопасен, потому что причуда в том, как разработаны MD5 (и большинство других хеш-функций), означает, что если вы знаете H (m), вы можете легко вычислить H (m || m2) для любого m2 - поэтому, если вы использовали MD5 (K || param1 = 5), кто-то может снять это с провода, а затем создать MD5 (K || param1 = 5, param2 = 666). (Возможно, это немного более технический, чем вас интересует, но это называется свойством расширения длины ).
Однако, хотя MD5 (K || msg), вероятно, «в порядке», вы Лучше использовать что-то вроде HMAC, потому что на самом деле он был разработан как MAC. У MD5 много проблем, но ничего напрямую не влияет на его использование в качестве MAC (пока что MD4 был сломан таким образом). Поэтому для обеспечения перспективности (и проверки) используйте HMAC с SHA-1 или SHA-256. Даже если вы не хотите использовать криптографическую библиотеку,
Что ж, предположим, я знаю секрет, тогда я могу сгенерировать сигнатуру и передать ее. То, что делалось для одного из моих стартапов, - это еще больше продвинуть параметр sig, заставив sig полагаться на другие параметры, а также на идентификатор запроса (UUID) и временную метку и сохранить этот UUID (соображения безопасности на пару часов, чтобы запретить хакеру вызывая одну и ту же функцию снова и снова). Таким образом, вы не сможете снова вызвать тот же вызов, вам придется сгенерировать новый UUID, и если хакер заменит UUID в параметре, сигнатура становится недействительной, и он не знает, как сгенерировать сигнатуру, потому что, кроме секрета, мы также создание подписи на основе внутреннего ключа длиной 30 символов. So essenity
MD5 (Алфавитный список параметров + APiKEY + callID + Secert + someLonginternalKey)
не уверен, ответил ли я на ваш вопрос, но это еще один способ защиты api
В этом случае я бы посоветовал использовать цифровые подписи, поскольку они более подходят. Цифровой подписи, например, над апикием более чем достаточно. Вам даже не нужны секреты и хеш. Вам нужно только убедиться, что цифровая подпись остается частной (как и хеш md5).
Если вы хотите предотвратить повторную атаку, вам нужна некоторая случайность в каждом запросе. Поэтому я бы предложил следующее:
Сервер -> API: Nonce (= некоторое случайное число)
API -> Сервер: Enc (nonce + цифровая подпись)
это зашифровано с помощью открытого ключа сервера. и цифровая подпись размещается с закрытым ключом сервера.
Теперь у вас не может быть повторной атаки. Однако по-прежнему существует проблема человека в средней атаке, но исправить это не так уж и тривиально (но вполне выполнимо). Поэтому в зависимости от желаемого / необходимого уровня безопасности вы можете адаптировать свои технические меры.
Нет. Целостность других параметров (param1 и param2 в вашем примере) не защищена. Злоумышленник может перехватить вызов и изменить их по своему усмотрению, прежде чем переадресовать его. apiCallId
предотвращает только повторы, но не изменение первого вызова.
Я не эксперт. Если бы я увидел это сразу же, вероятно, скрываются другие проблемы.