Вопрос по java, elliptic-curve, cryptography – Как сжать или закодировать открытый ключ эллиптической кривой и поместить его в сеть?

7

Я разрабатываю Распределенную цифровую подпись, которая подписывает документ и отправляет его по сети на сервер приложений. Я использую программирование сокетов в 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 - мой проект

Какой API вы используете? Например. какое имя класса FQN для экземпляра шифрования и класса ECKeyPair? Хотя, как уже было сказано, вы можете получить значения BigInteger и сохранить их как есть. Eugene Kuleshov
Хотите использовать точечное сжатие? Это метод, при котором вы только сериализуете координату x и знак координаты y, а затем используете уравнение кривой для восстановления координаты y. CodesInChaos
Как вы представляете их в памяти? Они просто большие целые числа, их сериализация должна быть легкой. CodesInChaos
класс для криптографического экземпляра - мой собственный. Clickmit Wg
да, но в дополнение к сжатию я хочу поместить сжатый открытый ключ в общий сетевой реестр, чтобы два или более сервера приложений использовали его для проверки подписи. Clickmit Wg

Ваш Ответ

2   ответа
3

что реализация 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);
    }

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

Точки эллиптической кривой почти всегда кодируются с использованием кодировки, указанной в 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);

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

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

Похожие вопросы