Как сжать или закодировать открытый ключ эллиптической кривой и поместить его в сеть?

Я разрабатываю Распределенную цифровую подпись, которая подписывает документ и отправляет его по сети на сервер приложений. Я использую программирование сокетов в Java для этого. Я думаю, что открытый ключ должен быть закодирован или сжат, т.е. значения x и y как-то представлены в виде отдельных двоичных данных и сохранены в открытом реестре или сети. Но я не знаю, как это сделать в Java.

        // I have class like this 
           public class CryptoSystem{                  

               EllipticCurve ec = new EllipticCurve(new P192());

               //-------------------
               //--------------------

               public ECKeyPair generatekeyPair()
               {
                  return ECKeyPair(ec);

               }


            }    
        // i don't think i have problem in the above


    CryptoSystem crypto = new CryptoSystem();
    ECKeyPair keyPair = crypto.generateKeyPair();
    BigInteger prvKey = keyPair.getPrivateKey();
    ECPoint pubKey = keyPair.getPublicKey();
     // recommend me here to  compress and send it  the public key to a shared network.

Я хочу знать, как кодировать открытый ключ и параметры домена, чтобы верификатор подписи расшифровал его, чтобы использовать его. Потому что, когда вы отправляете их по сети в верификатор, вам придется кодировать как однобайтовый массив Я не использую Bouncy Castle Provider. Вся реализация алгоритма ECDSA - мой проект

 Eugene Kuleshov07 июн. 2012 г., 19:48
Какой API вы используете? Например. какое имя класса FQN для экземпляра шифрования и класса ECKeyPair? Хотя, как уже было сказано, вы можете получить значения BigInteger и сохранить их как есть.
 CodesInChaos07 июн. 2012 г., 18:47
Хотите использовать точечное сжатие? Это метод, при котором вы только сериализуете координату x и знак координаты y, а затем используете уравнение кривой для восстановления координаты y.
 CodesInChaos07 июн. 2012 г., 18:46
Как вы представляете их в памяти? Они просто большие целые числа, их сериализация должна быть легкой.
 Clickmit Wg08 июн. 2012 г., 05:00
класс для криптографического экземпляра - мой собственный.
 Clickmit Wg07 июн. 2012 г., 19:21
да, но в дополнение к сжатию я хочу поместить сжатый открытый ключ в общий сетевой реестр, чтобы два или более сервера приложений использовали его для проверки подписи.

Ответы на вопрос(2)

что реализация BC использует кодировку X9.63, так что это будут довольно стандартизированные кодировки. Вам нужно будет добавить провайдера Bouncy Castle в свой JRE (Security.addProvider(new BouncyCastleProvider())см. бодрую документацию.

public static void showECKeyEncodings() {

    try {
        KeyPairGenerator kp = KeyPairGenerator.getInstance("ECDSA");
        ECNamedCurveParameterSpec ecSpec = ECNamedCurveTable
                .getParameterSpec("prime192v1");
        kp.initialize(ecSpec);
        KeyPair keyPair = kp.generateKeyPair();

        PrivateKey privKey = keyPair.getPrivate();
        byte[] encodedPrivKey = privKey.getEncoded();
        System.out.println(toHex(encodedPrivKey));

        PublicKey pubKey = keyPair.getPublic();
        byte[] encodedPubKey = pubKey.getEncoded();
        System.out.println(toHex(encodedPubKey));

        KeyFactory kf = KeyFactory.getInstance("ECDSA");
        PublicKey pubKey2 = kf.generatePublic(new X509EncodedKeySpec(encodedPubKey));
        if (Arrays.equals(pubKey2.getEncoded(), encodedPubKey)) {
            System.out.println("That worked for the public key");
        }

        PrivateKey privKey2 = kf.generatePrivate(new PKCS8EncodedKeySpec(encodedPrivKey));
        if (Arrays.equals(privKey2.getEncoded(), encodedPrivKey)) {
            System.out.println("That worked for the private key");
        }

    } catch (GeneralSecurityException e) {
        throw new IllegalStateException(e);
    }

}
 05 дек. 2018 г., 12:59
@ K.Os Пожалуйста, не делай этого. Так что это командная работа, я не даю здесь личных советов.
 18 мар. 2016 г., 10:32
Этот пример также работает в JDK 1.8, за исключением того, что вам нужно указать «EC» в KeyPairGenerator и KeyFactory.
 18 мар. 2016 г., 12:48
Также "prime192v1" должен быть заменен на "secp192r1" в JDK 1.8.
 10 июн. 2012 г., 19:14
В этом случае я бы умолял вас взглянуть на очень допустимую базовую реализацию Bouncy Castle, если не для копирования, то просто посмотреть стандартную кодировку X9.62 параметров домена. BSI TR-03111 также имеет (более простой) метод кодирования параметров домена.
 18 мар. 2016 г., 14:11
@kravietz Да, и вы должны использоватьECGenParameterSpec а также для генератора пар ключей. Я отредактирую ответ, чтобы отразить эти изменения как можно скорее. Забавно, но кодировка BC и Oracle отличается; закрытый ключ содержит (необязательный) открытый ключ в случае с Oracles & apos; Кодирование ASN.1, и оно не относится к BC. Таким образом, оба являются правильными и совместимыми, они просто немного отличаются.

Точки эллиптической кривой почти всегда кодируются с использованием кодировки, указанной в X9.62.

Необязательно использовать точечное сжатие. Кодировать с использованием сжатия точек тривиально, но декодирование сжатых точек требует немного больше работы, поэтому, если вам действительно не нужно сохранять дополнительные байты, я бы не стал беспокоиться. Дайте мне знать, если вам это нужно, и я добавлю детали. Вы можете распознать точки в кодировке X9.62 со сжатием точек по первому байту, который будет 0x02 или 0x03.

Кодирование без точечного сжатия действительно просто: начните с 0x04 (чтобы указать отсутствие сжатия). Затем следует сначала координата x, затем координата y, оба дополнены нулями слева до размера в байтах поля:

int qLength = (q.bitLength()+7)/8;
byte[] xArr = toUnsignedByteArray(x);
byte[] yArr = toUnsignedByteArray(y);
byte[] res = new byte[1+2*qLength];
res[0] = 0x04;
System.arraycopy(xArr, 0, res, qLength - xArr.length, xArr.length);
System.arraycopy(yArr, 0, res, 2* qLength - yArr.length, nLength);

Расшифровка это, конечно, тривиально.

 Clickmit Wg08 июн. 2012 г., 05:42
спасибо, я понимаю твой ответ. где открытый ключ я должен сохранить для использования одним или несколькими серверами приложений в удаленной области?
 Clickmit Wg08 июн. 2012 г., 06:01
как насчет параметров домена (q, a, b, G, n, h), как они передаются приложениям удаленной проверки подписи, поскольку динамически выбираются эллиптические кривые в качестве знака u. p-192, p-224, ...., p-512 рекомендуемые параметры домена эллиптической кривой
 08 сент. 2017 г., 17:44
Можно ли добавить процедуру для работы со сжатыми ключами? Спасибо
 08 июн. 2012 г., 08:06
@Clickmit: я предполагаю, что у вас есть статические параметры домена и просто жестко запрограммированы их на каждом конце. Если у вас есть небольшой список поддерживаемых кривых, я бы просто сделал что-то вроде добавления целого числа, указывающего, какую кривую вы используете. Если вы хотите закодировать все параметры домена, для этого тоже есть стандарты (посмотрите структуру ECDomainParameters ASN.1), но я думаю, что вы должны найти для этого кодер DER ASN.1. Ручное кодирование кодирования такой структуры не является тривиальным.

Ваш ответ на вопрос