2014-09-15 2 views
2

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

Попробуйте зашифровать что-то двумя цифрами, скажем «11» или «12» и посмотреть, существует ли расхождение. Если нет, продолжайте добавлять цифры до появления. Кажется, что алгоритм JS делает какую-то упаковку, которая, вероятно, не существует. – mikeazo

+0

Он разбивается на несколько персонажей. От 0 до 9, вывод одинаков. –

+0

Эти цифры и все остальное здесь довольно отрывочно. Модуль тривиально факторизуем (37 - фактор !!), а код javascript нескомментирован и трудно понять. Вы на самом деле не используете Bouncycastle, за исключением фабрики ключей, и я не понимаю, зачем вам Bouncycastle в любом случае. Вероятно, вам нужно будет получить экземпляр RSA с «NOPADDING», указанным для заполнения, а затем реализовать дополнение для соответствия javascript. Или просто используйте javascript самостоятельно и вообще пропустите java. –

ответ

1

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

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

for i=0, i<len(old_array), i+=2: 
    new_array[i] = old_array[i] + (old_array[i+1] << 8) 

Для входной строки длины 1 (говорят, что это "1"), вы бы old_array = [0x31, 0x00, ...] (некоторые более заполнение нулями). Итак, new_array = [0x31 + (0x00 < < 8 == 0x00) = 0x0031, ...] (больше нулевого заполнения). Обратите внимание, что old_array == new_array (в какой-то мере new_array на самом деле короче, но все равно все нули, поэтому значение при преобразовании в большое целое одинаково).

С длиной 2 строки ввода (скажем, «12») у вас будет old_array = [0x31, 0x32, 0x00, ...] (больше отступов). Итак, new_array = [0x31 + (0x32 < < 8 == 0x3200) = 0x3231, 0x0000]. Обратите внимание, что это не то же самое, что и old_array.

Поэтому, чтобы исправить вашу проблему, вам необходимо осуществить упаковку. Затем зашифруйте упакованный массив.

Библиотека JS также делает еще одну вещь, которую вы не делаете, что может быть или не быть проблемой. Если ваши незашифрованные тексты становятся слишком длинными, библиотека JS разрывает их и шифрует их отдельно (это размер блока в библиотеке JS).

Смежные вопросы