Несоответствие между реализациями RSA

Я не крипто-парень, поэтому я знаю почти все об этих вещах. Я должен взаимодействовать с системой, использующей криптографию RSA. При использовании их ключей я сталкиваюсь с проблемой получения разных шифров для одного и того же ввода/ключа. Библиотека https://code.google.com/p/pajhome/source/browse/trunk/crypt/md5/rsa/RSA.js?r=133, и я использую поставщик Java BouncyCastle RSA следующим образом:

BigInteger e = new BigInteger("9d7aa162117a8a9610ed2ddea713d7b", 16);
BigInteger m = new BigInteger("c9869917572adbb60a2c30ddec2551f", 16);

RSAPublicKeySpec spec = new RSAPublicKeySpec(m, e);
KeyFactory keyFac = KeyFactory.getInstance("RSA", "BC");
PublicKey pubKey = keyFac.generatePublic(spec);

Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);

// UNENCRYPTED_LOGIN = "201211130215"
// UNECRYPTED_TYPE = "1"

byte[] login = cipher.doFinal(UNENCRYPTED_LOGIN.getBytes("ASCII"));
byte[] type = cipher.doFinal(UNENCRYPTED_TYPE.getBytes("ASCII"));

// login = 00d571a40ef7359b2e9e10b7c5dd621c
// should be 02f0cc389fb88e6b4aaa4e2477858ca9

// type = 0a5c2e176c81b23b2e1dd635f2427c0f
// it is correct
1 ответ

Проблема заключается в методе упаковки из строк 52-65 в источнике JS, с которым вы связаны. Он работает для строк с 1 символом, но будет иметь проблемы при выполнении больших строк.

Чтобы проиллюстрировать проблему, рассмотрите, что происходит с длиной строки 1. Код JS создает массив и помещает значение ascii символа в массив. Затем заполняет массив нулями. Алгоритм упаковки создает новый массив, упаковывая 2 элемента массива в одно значение в новом массиве. Он делает что-то вроде этого:

for i=0, i
<p> Для строки ввода длиной 1 (скажем, это "1") у вас будет old_array = [0x31, 0x00,...] (еще некоторое заполнение нуля). Итак, new_array = [0x31 + (0x00 << 8==0x00)=0x0031,...] (больше нулевого заполнения). Обратите внимание, что old_array==new_array (в какой-то мере new_array на самом деле короче, но все равно все нули, поэтому значение при преобразовании в большое целое одинаково).</p> <p> С длиной строки ввода 2 (скажем, "12") у вас будет old_array = [0x31, 0x32, 0x00,...] (больше отступов). Итак, new_array = [0x31 + (0x32 << 8==0x3200)=0x3231, 0x0000]. Обратите внимание, что это не то же самое, что и old_array.</p> <p> Поэтому, чтобы исправить вашу проблему, вам необходимо реализовать упаковку. Затем зашифруйте упакованный массив.</p> <p> Библиотека JS также делает еще одну вещь, которую вы не делаете, что может быть или не быть проблемой. Если ваши незашифрованные тексты становятся слишком длинными, библиотека JS разрывает их и шифрует их отдельно (это размер блока в библиотеке JS).</p>

licensed under cc by-sa 3.0 with attribution.