Преобразование открытого ключа Ed25519 в открытый ключ x25519 на Java

Я пытаюсь преобразовать открытый ключ Ed25519 в открытый ключ x25519 на Java, используя пакет lazysodium:

import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

import com.goterl.lazysodium.LazySodium;
import com.goterl.lazysodium.LazySodiumJava;
import com.goterl.lazysodium.SodiumJava;

public class KeyOps {

    public static PublicKey ed25519ToX25519(PublicKey ed25519PublicKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {
        byte[] x25519PublicKeyBytes = new byte[32];
        LazySodium lazySodium = new LazySodiumJava(new SodiumJava());
        byte[] ed25519PublicKeyBytes = new byte[32];
        System.arraycopy(ed25519PublicKey.getEncoded(), 12, ed25519PublicKeyBytes, 0, 32);
        lazySodium.convertPublicKeyEd25519ToCurve25519(x25519PublicKeyBytes, ed25519PublicKeyBytes);
        return KeyFactory.getInstance("X25519", "BC").generatePublic(new X509EncodedKeySpec(x25519PublicKeyBytes));
    }

}

... где ed25519PublicKey будет генерироваться следующим образом:

KeyPair keyPair = KeyPairGenerator.getInstance("Ed25519", "BC").generateKeyPair();
PublicKey ed25519PublicKey = keyPair.getPublic();

Однако я получаю случайные ошибки, как одна из следующих:

An exception occured while executing the Java class. encoded key spec not recognized: failed to construct sequence from byte[]: Extra data detected in stream

or

An exception occured while executing the Java class. encoded key spec not recognized: failed to construct sequence from byte[]: corrupted stream - out of bounds length found: 57 >= 54

(57 и 54 могут быть другими значениями)

Могу я узнать, что здесь не так? Как мне конвертировать Ed25519 pk в x25519 pk и конвертировать его обратно в формат PublicKey?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Хорошо, я понял это.

Я понятия не имею, как закодировать X25519 pk с помощью X509EncodedKeySpec на Java, поэтому я создаю его вручную...

    public static PublicKey ed25519ToX25519(PublicKey ed25519PublicKey) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException {
        byte[] x25519PublicKeyBytes = new byte[32];
        LazySodium lazySodium = new LazySodiumJava(new SodiumJava());
        byte[] ed25519PublicKeyBytes = new byte[32];
        System.arraycopy(ed25519PublicKey.getEncoded(), 12, ed25519PublicKeyBytes, 0, 32);
        boolean conversion_success = lazySodium.convertPublicKeyEd25519ToCurve25519(x25519PublicKeyBytes, ed25519PublicKeyBytes);
        if (!conversion_success) {
            System.out.println("Conversion failed!");
            System.exit(1);
        }

        byte[] x509Header = new byte[]{
            0x30, 0x2a, // SEQUENCE, length 42
            0x30, 0x05, // SEQUENCE, length 5
            0x06, 0x03, 0x2b, 0x65, 0x6e, // OID for X25519
            0x03, 0x21, 0x00 // BIT STRING, length 33
        };
        // Combine the header and the key bytes
        byte[] x509EncodedKey = new byte[x509Header.length + x25519PublicKeyBytes.length];
        System.arraycopy(x509Header, 0, x509EncodedKey, 0, x509Header.length);
        System.arraycopy(x25519PublicKeyBytes, 0, x509EncodedKey, x509Header.length, x25519PublicKeyBytes.length);

        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(x509EncodedKey);
        KeyFactory keyFactory = KeyFactory.getInstance("X25519");
        PublicKey x25519PublicKey = keyFactory.generatePublic(keySpec);

        return x25519PublicKey;
    }

Другие вопросы по теме