Что вы пытаетесь сделать, так это реализовать так называемую «полагающуюся сторону», что означает, что ваш веб-сервис будет полагаться на подтверждение личности, предоставляемое токеном FIDO U2F.
Для этого вам необходимо знать спецификации U2F. В частности, как должна быть реализована парадигма «вызов-ответ» и как работают идентификаторы и фасеты приложений. Это подробно описано в спецификации.
Вы правы: фактический код, необходимый для работы с FIDO U2F из внешнего интерфейса вашего приложения, почти тривиален (то есть, если вы используете «высокоуровневый» JavaScript API, а не «низкоуровневый» MessagePort API) . Однако вашему приложению необходимо будет работать с сообщениями, сгенерированными токеном, и проверять их. Это нетривиально.
Чтобы проиллюстрировать, как можно реализовать сайт проверяющей стороны, я приведу несколько примеров кода, взятых из Virtual FIDO U2F Token Extension, который я запрограммировал недавно по академическим причинам. Вы можете увидеть страницу с полным примером кода.
Прежде чем ваши пользователи смогут использовать свои токены FIDO U2F для аутентификации, им необходимо зарегистрировать его у вас. Чтобы они могли это сделать, вам нужно вызвать window.u2f.register
в их браузере. Для этого вам нужно указать несколько параметров (опять же; подробности читайте в спецификации). Среди них проблема и id вашего приложения. Для веб-приложения этот id должен быть веб-источником веб-страницы, запускающей операцию 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;
};
Эти данные содержат несколько элементов, с которыми ваше приложение должно работать.
![Зарегистрируйте карту ответного сообщения о регистрации FIDO U2F](https://i.stack.imgur.com/dApXP.png)
- Открытый ключ сгенерированной пары ключей - вам необходимо сохранить его для будущего использования при аутентификации.
- Ключевой дескриптор сгенерированной пары ключей - вам также необходимо сохранить его для будущего использования.
- Сертификат - вам необходимо проверить, доверяете ли вы этому сертификату и ЦС.
- Подпись - вам необходимо проверить, действительна ли подпись (т.е. соответствует ли ключ, хранящийся в сертификате), и соответствуют ли подписанные данные ожидаемым данным.
Я подготовил черновой вариант реализации для сервера проверяющей стороны на 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;
};
Вам необходимо проверить данные подписи, содержащиеся здесь.
![Зарегистрируйте карту ответного сообщения аутентификации FIDO U2F](https://i.stack.imgur.com/4s1WE.png)
- Вам необходимо убедиться, что подпись соответствует полученному ранее открытому ключу.
- Вам также необходимо убедиться, что подписанная строка является подходящей.
После того, как вы выполнили эти проверки, вы можете считать пользователя аутентифицированным. Краткий пример реализации кода на стороне сервера для этого также содержится на моем сервере пример.
person
mritz_p
schedule
29.10.2014