Ответ 1
То, что вы пытаетесь сделать, - это реализовать так называемую "полагающуюся сторону", что означает, что ваш веб-сервис будет полагаться на утверждение идентичности, предоставленное токеном FIDO U2F.
Для этого вам нужно понять спецификации U2F. Особенно, как должна быть реализована парадигма "запрос-ответ" и как работают функции и факсимиты приложений. Это подробно описано в спецификации.
Вы правы: фактический код, необходимый для работы с FIDO U2F из переднего конца вашего приложения, почти тривиален (то есть, если вы используете JavaScript-интерфейс высокого уровня, а не "низкоуровневый", MessagePort API). Однако ваше приложение должно работать с сообщениями, генерируемыми токеном, и проверять их. Это не тривиально.
Чтобы проиллюстрировать, как вы могли бы использовать сайт, полагающийся на сайт, я приведу несколько примеров кода, взятых из Virtual FIDO U2F Token Extension который я запрограммировал в последнее время по академическим причинам. Вы можете увидеть страницу для полного кода примера.
Прежде чем ваши пользователи смогут использовать свои токены 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;
};
Вам необходимо проверить данные подписи, содержащиеся в данном документе.
- Вам нужно убедиться, что подпись совпадает с открытым ключом, который вы получили ранее.
- Вам также необходимо проверить правильность подписанной строки.
После выполнения этих проверок вы можете проверить подлинность пользователя. Краткий пример реализации кода на стороне сервера для этого также содержится в моем примере .