Делаю авторизацию на сайте, пароль шифруется публичным RSA mod+e.
Ключ HEX
:
d3bcef1f00424f3261c89323fa8cdfa12bbac400d9fe8bb627e8d27a44bd5d59dce559135d678a8143beb5b8d7056c4e1f89c4e1f152470625b7b41944a97f02da6f605a49a93ec6eb9cbaf2e7ac2b26a354ce69eb265953d2c29e395d6d8c1cdb688978551aa0f7521f290035fad381178da0bea8f9e6adce39020f513133fb
Exp HEX
: 10001
или же DEC
65537
При шифровании на сайте онлайн - все работает и зашифированный текст валиден
Но, как только я пробую сделать тоже самое на node-rsa - итоговый шифр неверный.
const NodeRSA = require('node-rsa');
let key = new NodeRSA();
key = key.importKey({
n: Buffer.from('d3bcef1f00424f3261c89323fa8cdfa12bbac400d9fe8bb627e8d27a44bd5d59dce559135d678a8143beb5b8d7056c4e1f89c4e1f152470625b7b41944a97f02da6f605a49a93ec6eb9cbaf2e7ac2b26a354ce69eb265953d2c29e395d6d8c1cdb688978551aa0f7521f290035fad381178da0bea8f9e6adce39020f513133fb', 'hex'),
e: 65537
}, 'components-public');
const encrypted = key.encrypt('qwerty', 'hex');
console.log(encrypted);
Обновление ответа Быстрый ответ: в node-rsa нужно установить режим шифрования 'pkcs1'
key.setOptions({encryptionScheme: 'pkcs1'})
const encrypted = key.encrypt('qwerty', 'hex');
Развернутый ответ.
В RSA есть несколько способов дополнить открытый текст до полного блока (padding). Причина, по которой текст, зашифрованный в node-rsa, не проходил в веб-сайте, заключается в различных схемах паддинга. В node-rsa по-умолчанию используется схема pkcs1-oaep, а в библиотеке crypts/rsa, используемой на сайте, - схема pkcs1-pad2.
В node-rsa такая схема тоже поддерживается, называется 'pkcs1'
. Устанавливается вызовом функции key.setOptions({encryptionScheme: 'pkcs1'})
.
С сайтом я тоже разобрался. "Открытым ключом" они называют n
, "закрытым ключом" - d
, а экспонента e
у них фиксирована 65537
.
Для проверки я сгенерировал на сайте пару n
и d
, в node-rsa строку qwerty
, а на сайте благополучно расшифровал.
const NodeRSA = require('node-rsa');
let key = new NodeRSA();
n = Buffer.from("817d1e54c65d819ab659285c14742a7aa3ea0e94e37dc73594ce52fdb2d932281583dd3309e45498ec86a82de9a43d76998cc20c588073d664e464ddf37314a3", "hex");
d = Buffer.from("24b7ee19ec0627f24f330916d355fd95b9556dbd1aa55810019a603e40b1065f9dbc447d3a363dca4f2c1c87c1f204429088aaa5865c9f7de89bf0e114a228c1", "hex")
e = 65537
key = key.importKey({n: n, e: e}, "components-public")
key.setOptions({encryptionScheme: 'pkcs1'})
const encrypted = key.encrypt('qwerty', 'hex');
console.log(encrypted.toString("hex"))
Результат шифрования
1ed253c66f41658fb37c3f2386ed9507079d063816c4297a10af89d7e77cb5d525a72678b55e0d75cb6dfaec88bcd6179171d6bb8f6b3f41975d98138bdf8d3c
Проверка на сайте:
Исходный ответ
Если коротко, то ваш метод проверки шифрования неверен.
Если же более развёрнуто, то в вашем вопросе я вижу несколько странных вещей.
Можно ли сравнивать два шифртекста?node-rsa
реализует схему шифрования pkcs1_oaep
, которая определена в RFC 3447. Этой схеме сообщение перед шифрованием дополняется случайным паддингом. Поэтому каждый каждый раз, когда вы шифруете одну и ту же строку одним и тем же ключом, вы будете получать разные результаты. То есть невозможно проверить правильность шифрования, сравнивая с шифртекстом, полученном где-то в другом месте.
Правильность шифрования проверяется не сравнением с эталоном, а правильностью расшифрования. То есть вам нужно зашифровать в своей программе публичным ключом, а потом расшифровать где-то в другом месте приватным ключом. Если результат расшифрования совпадёт с результатом шифрования, то всё пучком.
Но! Не имея приватный ключ, вы не сможете проверить правильность вашего шифрования.
Формат ключа на выбранном вами сайтеСамо понятие "RSA ключ в формате hex" неоднозначно. Повсеместно для представления ключа используются несколько разных форматов: PKCS1, PKCS8, OpenSSH. Какой из этих форматов ожидает тот сайт, который вы показали?
На указанном вами сайте я нажал кнопку "генерировать" и получил пару публичный ключ - приватный ключ. Публичный ключ начинался с байтов "8f25". Но такие байты в начале не соответствуют ни форматам PKCS1/8-DER, ни OpenSSH. Ключи PKCS в кодировке DER должны начинаться с 0x30, а ключ OpenSSH в бинарном представлении начинается с байтов 00 00 00 07.
Странный сайт, одним словом.
То, как вы им пользуетесь, добавляет странности. Вы вводите n
в поле "Открытый ключ", а экспоненту в поле "Длина ключа". Но это неверно! Открытый ключ сам должен содержать и n
и экспоненту. И длина ключа не должна использоваться - длину ключа (количество битов в числе n
) программа должна сама извлекать из правильно закодированного публичного ключа.
Хочу чтобы результатом выполнения функции был массив массивов с объектами, которые получены из БД
Я только начал изучать создание исполняемого jar архива из командной строкиС помощью команды jar создал файл app
При нажатии на кнопку, определенную во фрагменте выкидывает NullPointerExceptionСам фрагмент: