Существует ли стандартизованная кодировка фиксированной длины для открытых ключей ЕС?

Мне было интересно, был ли (и, я надеюсь, есть) стандарт для размера открытого ключа для ECDH (Elliptic Curve Diffie-Hellman) и ECDSA (алгоритм цифровой подписи эллиптической кривой) для каждого типа кривой над первичными полями (192, 224, 256, 384 и 521).

Ответы

Ответ 1

Если вы используете одну из "названных кривых", размер открытого ключа фиксируется и зависит от "размера поля" вашей базовой кривой.

Сжатое или несжатое представление

Размер публичных ключей зависит от того, используется ли "несжатое" представление или "сжатое" представление. В несжатой форме размер открытого ключа равен удвоенному размеру поля (в байтах) + 1, в сжатой форме - размер поля + 1. Итак, если ваша кривая определена на secp256r1 (также называемый NIST P-256 или X9.62 prime256v1), тогда размер поля составляет 256 бит или 32 байта. И поэтому открытый ключ будет в точности равным 65 байтам (32 * 2 +1) в несжатой форме и 33 байта (32 +1) в сжатой форме.

Несжатая форма состоит из 0x04 (по аналогии с тегом DER OCTET STRING) плюс конкатенация двоичного представления координаты X плюс двоичное представление координаты y публичной точки.

GF (2 ^ p) случай

Если базовое поле GF (2 ^ p), то x и y можно рассматривать как элементы из [0, n-1]. Они кодируются обычным способом, когда целые числа кодируются, а оставшееся пространство для заполнения точно log2 (p)/8 байтов заполняется нулями.

GF (2 ^ m) случай

Для GF (2 ^ m) x и y можно рассматривать как многочлены a_0x_0 +... + a_m-1 с коэффициентами a_i 0 или 1. Их двоичное представление является просто конкатенацией коэффициентов.

Дальнейшее чтение

Точные подробности можно найти в SEC1v2. (В частности, раздел 2.3.3. Эллиптическая кривая-точка-октет-преобразование строк на стр. 10 и 11.)

Ответ 2

Я долго искал ответ и хотел поделиться с вами на Java. Моя задача - получить размер ключа от X509Certificate (веб-сайт будет правильным)

Метод # 1 - фактический расчет:

ECPublicKeyImpl ecPublicKey = (ECPublicKeyImpl) certificate.getPublicKey();
int publicKeyLength = (ecPublicKey.getEncodedPublicValue().length - 1) / 2 * 8;

(Проверка, если первый байт может быть добавлен 0x04)

Метод № 2 - извлечение из некоторых "внутренних":

ECParameterSpec spec = ecPublicKey.getParams();
AlgorithmParameters algorithmParameters = AlgorithmParameters.getInstance("EC");
algorithmParameters.init(spec);
Provider provider = algorithmParameters.getProvider();
provider.get("KeyPairGenerator.EC KeySize");