Как использовать FIDO U2F, чтобы пользователи могли проходить аутентификацию на моем сайте?
Учитывая весь недавний шум вокруг спецификации FIDO U2F, я хотел бы внедрить FIDO U2F в тестовом режиме на испытательном стенде, чтобы быть готовым к предстоящему развертыванию окончательной спецификации.
Пока у меня есть ключ безопасности FIDO U2F от Yubico и расширение FIDO U2F (Universal 2nd Factor), установленное в Chrome. Мне также удалось настроить ключ безопасности для работы с моим входом в Google.
Теперь я не уверен, как использовать этот материал для моего собственного сайта. Я просмотрел страницу Google Github для проекта U2F и проверил интерфейс веб-приложения. Это выглядит очень просто (только JavaScript). Итак, является ли реализация второго фактора аутентификации с помощью FIDO столь же простой, как реализация нескольких вызовов JavaScript? Все, что, кажется, происходит для регистрации в примере, это:
var registerRequest = {
appId: enrollData.appId,
challenge: enrollData.challenge,
version: enrollData.version
};
u2f.register([registerRequest], [], function (result) {
if (result.errorCode) {
document.getElementById('status')
.innerHTML = "Failed. Error code: " + result.errorCode;
return;
}
document.location = "/enrollFinish"
+ "?browserData=" + result.clientData
+ "&enrollData=" + result.registrationData
+ "&challenge=" + enrollData.challenge
+ "&sessionId=" + enrollData.sessionId;
});
Но как я могу использовать это для реализации самостоятельно? Смогу ли я использовать обратный вызов из этого метода вызова для регистрации пользователя?
2 ответа
То, что вы пытаетесь сделать, это реализовать так называемую "доверяющую сторону", то есть ваша веб-служба будет полагаться на подтверждение личности, предоставленное токеном FIDO U2F.
Вам нужно будет понять спецификации U2F, чтобы сделать это. Особенно о том, как должна быть реализована парадигма "вызов-ответ" и как работают идентификаторы приложений и аспекты. Это подробно описано в спецификации.
Вы правы: фактический код, необходимый для работы с FIDO U2F из внешнего интерфейса вашего приложения, является почти тривиальным (то есть, если вы используете высокоуровневый JavaScript API, а не низкоуровневый MessagePort API), Однако вашему приложению необходимо работать с сообщениями, сгенерированными токеном, и проверять их. Это не тривиально.
Чтобы проиллюстрировать, как вы могли бы реализовать сайт проверяющей стороны, я приведу несколько примеров кода, взятых из Расширения токена Virtual FIDO U2F, которое я запрограммировал в последнее время по академическим причинам. Вы можете увидеть страницу с полным примером кода.
Прежде чем ваши пользователи смогут использовать свои токены FIDO U2F для аутентификации, они должны зарегистрировать его у вас. Чтобы позволить им сделать это, вам нужно позвонить window.u2f.register
в их браузере. Для этого вам нужно предоставить несколько параметров (опять же, подробности читайте в спецификации). Среди них вызов и идентификатор вашего приложения. Для веб-приложения этот идентификатор должен быть веб-источником веб-страницы, запускающей операцию FIDO. Давайте предположим, что это example.org
:
window.u2f.register([
{
version : "U2F_V2",
challenge : "YXJlIHlvdSBib3JlZD8gOy0p",
appId : "http://example.org",
sessionId : "26"
}
], [], function (data) {
});
Как только пользователь выполнит "тест на присутствие пользователя" (например, прикоснувшись к токену), вы получите ответ, который является объектом JSON (более подробную информацию см. В спецификации).
dictionary RegisterResponse {
DOMString registrationData;
DOMString clientData;
};
Эти данные содержат несколько элементов, с которыми ваше приложение должно работать.
- Открытый ключ сгенерированной пары ключей. Вам необходимо сохранить его для использования при аутентификации в будущем.
- Дескриптор ключа сгенерированной пары ключей - Вы также должны сохранить это для будущего использования.
- Сертификат - Вам необходимо проверить, доверяете ли вы этому сертификату и ЦС.
- Подпись. Необходимо проверить, действительна ли подпись (т. Е. Подтверждает ли ключ, хранящийся вместе с сертификатом), и являются ли подписанные данные ожидаемыми данными.
Я подготовил черновой вариант реализации для сервера проверяющей стороны на Java, который показывает, как извлечь и проверить эту информацию в последнее время.
Когда регистрация завершена и вы каким-то образом сохранили детали сгенерированного ключа, вы можете подписывать запросы.
Как вы сказали, это может быть начато коротко и приятно через высокоуровневый JavaScript API:
window.u2f.sign([{
version : "U2F_V2",
challenge : "c3RpbGwgYm9yZWQ/IQ",
app_id : "http://example.org",
sessionId : "42",
keyHandle: "ZHVtbXlfa2V5X2hhbmRsZQ"
}], function (data) {
});
Здесь вам необходимо предоставить дескриптор ключа, который вы получили при регистрации. Еще раз, после того, как пользователь выполнит "тест присутствия пользователя" (например, прикоснувшись к токену), вы получите ответ, который является объектом JSON (снова, см. Спецификацию для более подробной информации)
dictionary SignResponse {
DOMString keyHandle;
DOMString signatureData;
DOMString clientData;
};
Вам необходимо проверить данные подписи, содержащиеся в этом документе.
- Вы должны убедиться, что подпись соответствует открытому ключу, который вы получили ранее.
- Вы также должны проверить, что подписанная строка является подходящей.
После выполнения этих проверок вы можете считать пользователя аутентифицированным. Краткий пример реализации серверного кода для этого также содержится в моем примере с сервером.
Я недавно написал для этого инструкции, а также перечислил все библиотеки U2F-сервера (большинство из них комплектуются полностью работающим демонстрационным сервером) по адресу developers.yubico.com/U2F. Цель состоит в том, чтобы позволить разработчикам реализовать / интегрировать U2F без необходимости читать спецификации.
Отказ от ответственности: я работаю разработчиком в Yubico.