Проверить подпись в openssl c ++, которая подписана JAVA DSA? - PullRequest
0 голосов
/ 11 октября 2018

У меня есть требование для проверки подписи в c ++, которая генерируется API подписи JAVA.У меня одинаковый набор открытых и закрытых ключей. Я также проверил, что подпись и проверка работает в c ++ .Но у меня возникают проблемы с проверкой подписи, созданной JAVA.Я просмотрел документацию и попробовал разные вещи, но я все еще не могу понять это.Я вставляю эквивалентный код C ++ с исходным кодом JAVA, использованным для проверки.

Оригинальный код JAVA:

public static boolean verify(byte[] data, byte[] _signature, byte[] _publicKey) throws GeneralSecurityException {
        Signature signatureInstance = Signature.getInstance("DSA", "SUN");
        signatureInstance.initVerify(getPublicKey(_publicKey));
        signatureInstance.update(data);
        return signatureInstance.verify(_signature);
    }

Код C ++:

//sign_buffer contains the binary signature.

    int ret = DSA_verify(NID_dsa, data, sizeof(data), sign_buffer,
                          sign_length, pubkey);
if (ret != 1) {
            cerr << "verify failed" << endl;
            exit(-1);
        }

У меня есть 3вопросы:

  • Это правильный способ проверки подписи?
  • Нужно ли хешировать данные перед проверкой?Если да, то как JAVA делает это до подписания?

1 Ответ

0 голосов
/ 11 октября 2018

Сигнатура DSA, сгенерированная кодом Java, кодируется как ASN.1.Предполагая, что вы сохранили его в файле с именем sig, вы можете проверить это с помощью команды openssl asn1parse, например:

$ openssl asn1parse -inform der -in sig -i
    0:d=0  hl=2 l=  44 cons: SEQUENCE          
    2:d=1  hl=2 l=  20 prim:  INTEGER           :64C91D32CC10D7B67A7994BE680FA2BB07C431E2
   24:d=1  hl=2 l=  20 prim:  INTEGER           :712F1C768CFFA704DA1BEFA5A36517CB4776E6FF

Для загрузки отформатированной подписи такого типа в OpenSSL DSA_SIG структура, вы должны использовать функцию d2i_DSA_SIG().Повторное использование имен ваших переменных:

const unsigned char *ptr = sign_buffer;
DSA_SIG *dsasig = d2i_DSA_SIG(NULL, &ptr, sign_length);

Значение ptr будет изменено, чтобы указывать за считанные байты, как объяснено в документации.

Действительно, у вас будетхешировать ваши байты данных перед проверкой, используя тот же алгоритм хеширования, что и при подписанииКажется, что "DSA "является синонимом для "SHA1withDSA".Я проверил это с помощью теста, но я бы порекомендовал быть максимально явным в вашем коде и использовать полное имя вместо неясного псевдонима.Пример кода для расчета дайджестов с помощью OpenSSL можно найти в вики-записи Дайджесты сообщений EVP .

Тогда вы наконец готовы выполнить проверку

verify_result = DSA_do_verify(mdvalue, mdlen, dsasig, dsapubkey);

Код возврата 1 обозначает успешную проверку, 0 обозначает неудавшуюся проверку, -1 - некоторую другую ошибку.

Рекомендуется использовать EVP -уровневые API в отличие от нижнего уровня DSA -APIs , но DSA_do_verify(), кажется, ближе к тому, что вы уже получили, и это также работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...