Функциональная совместимость между реализациями Java и Javascript Ed25519

И ed25519-java, и js-nacl имеют реализацию методов криптографической подписи ed25519. Однако я получил открытый ключ и подписанное сообщение (подписанное с использованием соответствующего закрытого ключа открытого ключа) от ed25519-java и попытался проверить подписанное сообщение с помощью открытого ключа в js-nacl. Это дало null значение, т.е. подписанное сообщение не может быть открыто с открытым ключом.

У меня такой вопрос, не должно ли быть возможно войти в Java и проверить подпись в Javascript? Если так, то если нет, то почему?

Java-код:

public static void main(String[] args) {
    byte[] privateKey = new byte[32];
    Arrays.fill(privateKey, (byte) 0);
    byte[] publicKey = ed25519.publickey(privateKey);
    byte[] signature = ed25519.signature("www.example.com".getBytes(), privateKey, publicKey);
    System.out.println("Signature: " + Base64.encodeBase64URLSafeString(signature) + "\nPublicKey: " + Base64.encodeBase64URLSafeString(publicKey));
    try{
        System.out.println("Verification: " + ed25519.checkvalid(signature, "www.example.com".getBytes(), publicKey));
    } catch (Exception e){
        System.out.println(e.getStackTrace());
    }
}

Вызов checkvalid возвращает true.

Выходная подпись: oFMU_mC_zzZcJP2C-uTqsyUHoyLUSnwirJbhcdkSTnj2nI_p-VgKAqN5bFMPKsKYiWvyiUgHWu3s4OyB9WbKDg

Выходной открытый ключ: O2onvM62pC1io6jQKm8Nc2UyFXcd4kOmOsBIoYtZ2ik

Код JavaScript:

var signature = "oFMU_mC_zzZcJP2C-uTqsyUHoyLUSnwirJbhcdkSTnj2nI_p-VgKAqN5bFMPKsKYiWvyiUgHWu3s4OyB9WbKDg";
var pk = "O2onvM62pC1io6jQKm8Nc2UyFXcd4kOmOsBIoYtZ2ik";

var nacl_factory = require('js-nacl');
var nacl = nacl_factory.instantiate();
var b64 = require('urlsafe-base64');
var x = nacl.crypto_sign_open(Uint8Array(b64.decode(signature)), Uint8Array(b64.decode(pk)));
response.send(x);

x является нулевым, но должен дать "www.example.com" как вывод, если подпись может быть открыта с открытым ключом.

Не уверен, влияет ли это на работу, но байтовые массивы Java подписаны, тогда как js-nacl использует Javascript Uint8Array байтовые массивы без знака.

1 ответ

Реализации Ed25519 отличаются двумя способами:

  1. Формат закрытого ключа немного отличается. Некоторые работают с расширенным закрытым ключом, другие просят как начальный, так и открытый ключ при подписании. Ваша реализация Java попадает в последнюю категорию.

    Эта разница относится только к функции подписи, но не к функции проверки. Это не вызывает никаких проблем для вас.

  2. Некоторые реализации используют "поле подписи", где подпись возвращает объединение подписи и сообщения (signedMessage.Length = 64 + message.Length). При проверке они ожидают, что подписанное сообщение будет введено. Исходная реализация NaCl и ваша реализация javascript попадают в эту категорию.

    Некоторые реализации возвращают 64-байтовую подпись. Они ожидают, что открытый текст в качестве отдельного параметра при проверке. Ваша реализация Java попадает в эту категорию.

    Это несоответствие вызывает ваши проблемы. Чтобы это исправить нужно пройти concat(signature, message) в crypto_sign_open,

Вы должны прочитать статью Брайана Уорнера Ed25519 Keys для более подробного объяснения.

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