Веб-вход с использованием открытого / закрытого ключа ssl?

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

Я в основном хочу сделать что-то похожее на то, что делает SSH, но через Интернет. Возможно, пользовательский метод проверки подлинности HTTP (кроме «Дайджест»).

Я знаю, что это может быть невозможно сделать с помощью браузера акций, поэтому расширения для этой работы приемлемы (Chrome / Firefox).

Ключи в идеале должны быть зашифрованы на USB Stick. Когда USB-накопитель отключен, вход в систему невозможен (не нужно, чтобы браузер кэшировал его).

Это будет использоваться внутри страны.

Изменить: сертификаты клиентов будут тем, что я ищу, но как хранить эти сертификаты на USB-накопителе? Кроме того, есть ли информация о том, как аутентифицировать пользователя с помощью PHP?

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

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

Когда вы загружаете сертификат клиента в браузер, он загружается в хранилище сертификатов. Они различаются в зависимости от браузера и ОС. На OSX они идут в KeyChain. В Windows некоторые из них войдут в хранилище ключей ОС, а некоторые войдут в собственное хранилище ключей браузеров (Firefox, я считаю, работает таким образом). Но ни один из них не позволит вам определить внешнее хранилище ключей, а затем зашифровать и расшифровать ключ, который вы пытаетесь защитить, когда он читает и записывает с этого диска.

То, что вы делаете, было бы возможно только в том случае, если вы написали свое собственное настольное приложение (по сути, ваш собственный браузер), который сделал это для вас.

Возможно, вы можете сделать это с помощью приложения Adobe AIR. Adobe AIR поддерживает чтение и запись с USB-накопителя, он поддерживает зашифрованные базы данных (128-разрядный криптографический AES / CBC с SQLite), где вы можете хранить данные, которые вы пытаетесь защитить, и это кросс-платформенный.

При любом из этих решений вы, скорее всего, будете остановлены при необходимости обеспечения того, чтобы USB-ключ был подключен. Это, вероятно, сложно сделать. Как бы вы запретили пользователю просто копировать файлы с USB-ключа на жесткий диск и затем использовать ключ оттуда, чтобы им не нужно было использовать USB-ключ?

Чтобы добраться до этого уровня контроля, вам может потребоваться найти действительно собственное решение. C ++, Objective-C или Java. Java будет единственной, которая предложит вам кросс-платформенное решение.

Если USB-ключ является удобством для конечного пользователя, а не требованием, то Adobe AIR будет надежным решением. Если нет, то пришло время освежить ваши навыки разработки программного обеспечения на вашем ПК.

Вот как я сделал веб-логин, используя открытый / закрытый ключ RSA в php:

  • При регистрации сервер сохраняет открытый ключ пользователя и дает пользователю идентификатор
  • При входе в систему пользователю предлагается ввести свой идентификатор и закрытый ключ

Регистрация очень проста.

Но логин сделан таким образом:

  • Сервер генерирует строку, содержащую некоторые данные: случайную строку, текущее время, пользовательский ip
  • Эта строка зашифровывается дважды AES с двумя паролями: nonce1 = pass2( pass1( string ) )
  • Такая же строка снова зашифровывается с помощью AES с двумя паролями, но в обратном порядке: nonce2 = pass1( pass2( string ) ) и результат зашифровывается с помощью открытого ключа пользователя: nonce2encrypted = encryptPubKeyRSA( userPubKey, nonce2 )

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

Форма входа содержит три скрытых ввода: nonce1 , nonce2encrypted и nonce2 без значения.

Затем пользователю предлагается ввести свой секретный ключ в текстовое поле, которое находится вне <form> (чтобы быть уверенным, что он не будет отправлен на сервер в форме submit) , javascript расшифровывает nonce2encrypted и устанавливает дешифрованное значение в nonce2 . Затем текстовое поле с закрытым ключом удаляется из html с помощью javascript, чтобы быть уверенным, что он не будет храниться где-то в браузере или отправлен на сервер.

Сервер получает nonce1 и nonce2 и расшифровывает их с помощью этих двух паролей. Если дешифрованные значения совпадают, пользователь получает файл cookie и регистрируется.

PS Этот файл cookie также содержит некоторые зашифрованные данные, например user ip. Это не позволяет кому-то украсть этот файл cookie для входа из другого ip.

Вы можете просмотреть этот метод в действии ( проект на github )

Ответ на ваш вопрос «сегодня невозможно».

Технология существует сегодня в виде сертификатов, которые поддерживаются уже во всех браузерах. Но чтобы получить то, что вы хотите, браузеру нужно будет разрешить добавление и управление сертификатами в разделе «Менеджер паролей» своего пользовательского интерфейса. Люди хотели бы синхронизировать их между устройствами и т. Д.

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

Преимущество такого рода систем заключается в том, что вам никогда не придется отправлять свой пароль (закрытый ключ) на веб-сайт, на который вы входите. Но в остальном вы все еще имеете все управляющие действия, которые у вас есть сегодня с паролями.

Сертификаты клиентов – это ответ. Большинство / Все браузеры импортируют эти клиентские сертификаты как PKCS # 12 (.p12, .pfk).

Вы можете конвертировать существующий сертификат x509 в файл PKCS # 12 с открытым ключом (.crt), закрытым ключом (.key) и сертификатом CA (.crt). Вы можете сделать это с помощью OpenSSL, используя следующую команду:

 openssl pkcs12 -export -out client.p12 -inkey client.key -in client.crt -certfile ca.crt 

Если вы сами подписываете сертификаты, важно убедиться, что серийный сертификат отличается от других сертификатов. Если они одинаковы, вы можете столкнуться с ошибками, пытающимися импортировать файл .p12 (так что следите за -set_serial в примерах openssl).

К сожалению, единственный кросс-платформенный способ сделать сертификаты мобильными / съемными – использовать смарт-карту (используя PKCS # 11).

В Mac OS X Safari и Chrome получают доступ к своим сертификатам из цепочки ключей. Фактически вы можете создать собственный брелок на USB-накопителе (File -> New Keychain). После того, как вы создали брелок, вы можете просто перетащить файл .p12 в свой брелок. Что хорошо в этом, вы можете контролировать доступ к тому, что приложение имеет доступ к сертификатам, и вы можете заблокировать сам брелок после определенного количества бездействия.

С Safari это работает красиво. Если вы отключите флешку, она перестанет отправлять этот сертификат через пару секунд. Если вы подключите его обратно, он сразу же подберет его. Если вы заблокируете сертификат с помощью «Keychain Access», он запрашивает пароль. Это мешает вам правильно выбрасывать флэш-накопитель во время использования, но через минуту Safari выпускает свою блокировку.

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

Таким образом, похоже, что Safari является единственным браузером, поддерживающим это. У Firefox и Opera есть свои собственные хранилища ключей.

Если вы хотите скрыть свой собственный брелок на флеш-накопителе, вы можете создать невидимую папку, префиксную ей с периодом (например, «./.keys»). При создании брелка вы можете просмотреть невидимую папку в диалоговом окне, нажав Command + Shift + ".".