Регистрация или приглашение Проверка электронной почты без базы данных
Я хочу, чтобы моя база данных была чистой из-за устаревших почти-учетных записей, и я думал о том, что новые регистрации и приглашения помещают их данные в приветственное письмо в виде зашифрованного или хешированного URL-адреса. Как только ссылка в URL-адресе посещена, информация затем добавляется в базу данных в качестве учетной записи.
Есть ли что-то, что в настоящее время это делает? Любые ссылки, мысли или предупреждения о регистрации пользователя таким образом?
Спасибо!
Изменить:
Я составил рабочий пример, а URL - 127 символов.
http://localhost/confirm?_=hBRCGVqie5PetQhjiagq9F6kmi7luVxpcpEYMWaxrtSHIPA3rF0Hufy6EgiH%0A%2BL3t9dcgV9es9Zywkl4F1lcMyA%3D%3D%0A
Очевидно, что больше данных = более высокий url
def create
# Write k keys in params[:user] as v keys in to_encrypt, doing this saves LOTS of unnecessary chars
@to_encrypt = Hash.new
{:firstname => :fn,:lastname => :ln,:email => :el,:username => :un,:password => :pd}.each do |k,v|
@to_encrypt[v] = params[:user][k]
end
encrypted_params = CGI::escape(Base64.encode64(encrypt(compress(Marshal.dump(@to_encrypt)), "secret")))
end
private
def aes(m,t,k)
(aes = OpenSSL::Cipher::Cipher.new('aes-256-cbc').send(m)).key = Digest::SHA256.digest(k)
aes.update(t) << aes.final
end
def encrypt(text, key)
aes(:encrypt, text, key)
end
def decrypt(text, key)
aes(:decrypt, text, key)
end
# All attempts to compress returned a longer url (Bypassed by return)
def compress(string)
return string
z = Zlib::Deflate.new(Zlib::BEST_COMPRESSION)
o = z.deflate(string,Zlib::FINISH)
z.close
o
end
def decompress(string)
return string
z = Zlib::Inflate.new
o = z.inflate(string)
z.finish
z.close
o
end
Ответы
Ответ 1
Мысли:
-
Используйте истинный асимметричный шифр для "cookie", чтобы предотвратить создание ботов. Шифруйте "cookie" с помощью открытого ключа, проверьте его путем декодирования с помощью закрытого ключа.
Обоснование. Если для кодирования файла cookie был использован только base64 или другой алгоритм, было бы легко перепрограммировать схему и автоматически создавать учетные записи. Это нежелательно из-за спам-ботов. Кроме того, если учетная запись защищена паролем, пароль должен появиться в файле cookie. Любой, у кого есть доступ к ссылке регистрации, сможет не только активировать учетную запись, но и выяснить пароль.
-
Требовать повторного ввода пароля после активации по ссылке.
Обоснование. В зависимости от цели сайта вы можете улучшить защиту от подмены информации. Повторное ввод пароля после активации защищает от похищенных/поддельных ссылок активации.
-
При проверке ссылки активации убедитесь, что созданная им учетная запись уже не создана.
-
Как вы защищаете от двух пользователей одновременно создание учетной записи с тем же именем?
Возможный ответ: используйте электронную почту в качестве идентификатора входа и не требуйте уникального имени учетной записи.
-
Сначала проверьте адрес электронной почты, чем продолжить создание учетной записи.
Обоснование: это минимизирует информацию, необходимую для отправки в файл cookie.
Ответ 2
-
Есть несколько почтовых клиентов, которые разбивают URL-адреса после 80 букв. Я сомневаюсь, что вы можете разместить всю информацию там.
-
У некоторых браузеров есть ограничения для URL-адреса, Internet Explorer 8 имеет ограничение, например, 2083 символа.
Почему вы не регулярно очищаете базу данных (cron script) и удаляете все учетные записи, которые не были активированы в течение 24 часов?
Ответ 3
Я сделал почти то же самое раньше. У меня только 2 предложения для вас,
- Добавьте ключевую версию, чтобы вы могли повернуть ключ, не нарушая выдающегося подтверждения.
- Вам нужна отметка времени или срок действия, чтобы вы могли установить лимит времени на подтверждение, если хотите. Мы разрешаем одну неделю.
Что касается кратчайшего URL, вы можете сделать это, выполнив следующие изменения:
- Используйте режим шифрования потока, например, CFB, поэтому вам не нужно набирать размер блока.
- Сжатие текстового файла поможет, когда данные будут большими. Я имею флаг и использую только сжатие при сжатии данных.
- Используйте
Base64.urlsafe_encode64()
, чтобы URL-адрес не кодировался.
Ответ 4
Есть несколько проблем с вашим решением.
Во-первых, вы не устанавливаете IV шифра. На мой взгляд, это выявило серьезную ошибку в Ruby OpenSSL-оболочке - она не должна позволять вам выполнять шифрование или дешифрование до тех пор, пока не будут установлены оба параметра key
и iv
, но вместо этого он будет идти вперед и использовать IV всех -zeroes. Использование одного и того же IV каждый раз в основном устраняет большую пользу использования режима обратной связи в первую очередь.
Во-вторых, и, что более серьезно, у вас нет проверки подлинности. Одним из свойств режима CBC является то, что злоумышленник, имеющий доступ к одному сообщению, может изменить его, чтобы создать второе сообщение, в котором блок во втором сообщении имеет полностью контролируемое пользователем содержимое, за счет того, что предыдущий блок полностью искажен. (О, и обратите внимание, что режим CFB также является проблемой в этом отношении).
В этом случае это означает, что я могу запросить учетную запись с Фамилияю AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA и мой собственный адрес электронной почты, чтобы получить действительный URL. Затем я могу, не зная ключа, изменить адрес электронной почты на [email protected]
(и исказить последнее имя в этом процессе, что не имеет значения) и иметь действительный URL-адрес, который я могу отправить на ваш сервер и создать учетные записи для адреса электронной почты, которые я не контролирую.
Чтобы решить эту проблему, вам нужно вычислить HMAC по данным, связанным с секретом, который знает только сервер, и отправить его как часть URL-адреса. Обратите внимание, что единственная причина, по которой вы нуждаетесь в шифровании, - это защитить пароль пользователя, отличный от того, что он может быть просто текстовым и HMAC. Я предлагаю вам просто отправить URL-адрес примерно так:
?ln=Last%20Name&fn=First%20Name&[email protected]&hmac=7fpsQba2GMepELxilVUEfwl3%2BN1MdCsg%2FZ59dDd63QE%3D
... и у вас есть запрос на проверку пароля для пароля (кажется, нет причины отказываться от пароля назад и вперед).
Ответ 5
Я расскажу о конструкции, которая может работать.
Prerequisities:
- Библиотека криптографии с поддержкой RSA и некоторая защищенная хэш-функция H (например, SHA-1)
- Одна пара частных и открытых ключей
Дизайн:
- Уникальный идентификатор пользователя - это адрес электронной почты
- У учетной записи есть связанный пароль и возможные другие данные.
- Файл cookie активации хранится как можно меньше
Процесс:
- Пользователь запрашивает адрес электронной почты и пароль. После подачи формы cookie вычисляется как
cookie = ENCRYPT(CONCAT(email, '.', H(password)), public key)
- Отправляется электронная почта, содержащая ссылку на страницу активации с файлом cookie, например.
http://example.org/activation?cookie=[cookie]
- Страница активации
http://example.org/activation
расшифровывает файл cookie, переданный как параметр: data = SPLIT(DECRYPT(cookie, private key), '.')
- На той же странице активации пользователю предлагается ввести пароль (который должен быть хэширован до того же значения, что и в cookie) и любую другую информацию, необходимую для создания учетной записи.
- После отправки страницы активации создается новая учетная запись
Пожалуйста, укажите на что-либо, что я пропустил или какие-либо улучшения. Я был бы рад соответствующим образом обновить ответ.