bcrypto / btok

Cryptographic tokens
4 stars 4 forks source link

Команда генерации ключевой пары использует неверный тэг для открытого ключа #47

Closed andrewkostevich closed 5 years ago

andrewkostevich commented 5 years ago

Команда генерации ключевой пары кодирует открытый ключ тэгом 7F49, что справедливо только для RSA или (EC)DSA, в случае BIGN должен использоваться тэг 5F49

agievich commented 5 years ago

При нашем прочтении стандарта ISO 7816-8 тег 7F49 является универсальным. В стандарте он покрывает "interindustry template" для описания компонентов открытого ключа. Идея состоит в том, что под тегом размещаются объекты данных, которые характеризуют разные части открытого ключа: модуль и открытая экспонента в случае RSA или параметры эллиптической кривой и точка на ней в случае ECDSA. Каждый объект данных кодируется отдельно, порядок объектов может быть произвольным, что делает разбор данных под тегом достаточно громоздким.

В EIDAS тег позиционируется как описатель открытого ключа. Он покрывает ключи не только RSA и (EC)DSA, но и (EC)DH.

Таким образом, использование тега при кодировании открытого ключа Bign считаем разумным. Другое дело, что мы несколько упрощаем кодирование и не инкапсулируем открытый ключ как объект данных. Другими словами, используется конструкция der(7F49, pubkey) а не скажем конструкция der(7F49, der(86, pubkey)). Считаю упрощение кодирования допустимым, ведь контекст полностью понятен (идет речь о возвращаемом открытом ключе).

Семантика предлагаемого тега 5F49 требует пояснений.

Развилка:

  1. Ничего не менять.
  2. Возвращать "сырой" открытый ключ (без тега).

Я склоняюсь ко второму варианту. Он больше соответствует интерфейсам похожих команд (выработка ЭЦП, разбор токена).

andrewkostevich commented 5 years ago

Правила кодирования DER:

7F49 означает application specific composite с тэгом 49: для RSA и ECDSA открытый ключ является типом SEQUENSE, поэтому он composite. Для BIGN открытый ключ является примитивным типом, поэтому бит 6 равен 0 и тэг старший байт превращается в 5F.

В каком объеме использовать DER-кодирование в стандарте - это вопрос целостности логики стандарта. За основу был взята система команд eIDAS токена, в которой используется DER (и там как раз используется RSA, ECDSA, ECDH с типом composite).

agievich commented 5 years ago

Ok. У нас non-composite, поэтому я предлагаю вариант 2: "сырой" открытый ключ. Именно в "сыром виде" передаются хэш-значения, возвращаются ЭЦП и транспортируемые ключи. Не вижу никакого смысла в тегировании. Если не будет возражений, внесу в #45.

agievich commented 5 years ago

И еще. Если уж быть до конца последовательным, то следует (@olegotory?):

  1. Исключить двойное тегирование при передаче сообщений протоколов BAUTH/BPACE. Например, в BAUTH вместо der(7C, der(80, M1)) передавать der(80, M1).
  2. Исключить двойное тегирование в 12.2.9 (генерация ключевой пары): вместо der(B6, der(84, X)) передавать der(84, X).
olegotory commented 5 years ago

Не считаю, что исключить двойное тегирование для GENERAL AUTHENTICATE будет правильно. В iso 7814-4 для CDF команды GENERAL AUTHENTICATE сказано:

"When present, each data field shall contain an interindustry template referenced by tag '7C'. In the dynamic authentication template, the context-specific class (first byte from '80' to 'BF') is reserved for dynamic authentication data objects as listed in Table 71."

В таблице 71 iso 7816-4 указано: 80 - Witness (e.g., one or more positive numbers less than the public modulus in use) 81 - Challenge (e.g., one or more numbers, possibly zero, less than the public exponent in use) 82 - Response (e.g., one or more positive numbers less than the public modulus in use) 83 - Committed challenge (e.g., the hash-code of a large random number including one or more challenges) 84 - Authentication code (e.g., the hash-code of one or more data fields and a witness data object) 85 - Exponential (e.g., a positive number for establishing a session key by a key agreement technique) A0 - Identification data template In this context, ISO/IEC JTC 1/SC 17 reserves any other data object of the context-specific class (first byte from '80' to 'BF').

olegotory commented 5 years ago

По поводу команды GENERATE ASYMMETRIC KEY PAIR.

Для команды генерации ключевой пары нужно сделать параметр P1 = 80 (proprietary output format), сейчас у нас P1 = 82 (output format according to extended header list).

Исключить двойное тегирование в 12.2.9 (генерация ключевой пары): вместо der(B6, der(84, X)) передавать der(84, X).

Считаю, что двойное тэгирование исключить нельзя.

У нас тэг B6 отвечает за CRT (Control Reference Template): Digital signature - B6; Confidentiality - B8; Authentication - A4.

Тэг 84 говорит о том, что указывается ссылка на личный ключ (Private key reference).

agievich commented 5 years ago

Хорошо, тогда оставляем как есть. Исключаем только тегирование при возврате открытого ключа в <Generate Asymmetric Key Pair>? Или его тоже оставляем?

olegotory commented 5 years ago

Делаем параметр P1 = 80 и исключаем тэгирование открытого ключа.

Отмечу, что при генерации ключевой пары мы указываем тэг B6 (Digital signature), но у нас ключ используется как для подписи, так и для транспорта ключа. Не знаю можно ли так делать в нашем случае ... Как задать CRT для "Digital signature + Confidentiality" я пока не нашел.

agievich commented 5 years ago

Насколько я понимаю, P1 = 80 должно быть безусловно. Иначе в команде следует приводить CRT c extended header list, через который контролируются возвращаемые объекты данных.

Надо еще установить INS = 46 (INS = 47 как раз указывает на использование объектов данных в ответе).

Формально в CDF можно задать несколько CRT и, таким образом, добиться гибкой настройки "ЭЦП и (или) транспорт". Например, вот так

der(B6, der(84, X)) || der(B8, der(84, X))

можно задавать генерацию полнофункционального ключа, а опуская любой из конкатенированных CRT можно добиваться снижения функционала. Например, можно заблокировать использование ключа ЭЦП для транспорта и наоборот. Но нужна ли нам такая гибкость? Считаю, что нет. Ведь для лк в контексте BPKI подразумевается полный функционал. Поэтому надо требовать и B6, и B8. Как это сделать? Есть два варианта:

  1. Оставить CDF = der(B6, der(84, X)) и неявно считать, что B6 подразумевает B8.
  2. Задавать CDF = der(B6, der(84, X)) || der(B8, der(84, X)).

Второй вариант более строгий, но он и более громоздкий, в частности, требует проверки совпадения вхождений X.

agievich commented 5 years ago

Сохранен вариант 1. В #45 подкорректированы компоненты P1, INS команды GENERATE ASYMMETRIC KEY PAIR.