6

Я использую rsa.js v1.0 от http://www-cs-students.stanford.edu/~tjw/jsbn/ для шифрования строки ASCII в браузере. Строка на самом деле представляет собой 16-байтовый массив, содержащий ключ TripleDes двойной длины. С rsa v1.0 это работает. Байт-массив правильно расшифровывается на сервере (используя Bouncy Castle или Thales HSM) в виде массива размером 16 байт.RSA в javascript больше не поддерживает ASCII/байтовые массивы

например.

var zpk = hex2a("E0F8AD4092F81FC401E60ECB7F5B8F1A"); 
var rsa = new RSAKey(); 
rsa.setPublic(modulus, exponent); 
var res = rsa.encrypt(zpk); 
if (res) { 
    document.rsatest.zpkrsa.value = hex2b64(res); 
} 

При перемещении rsa.js v1.4 это не работает. Bouncy castle расшифровывает данные, но вместо 16-байтового массива теперь он составляет 25-байтовый массив.

Основное различие я вижу в rsa.js библиотеке в примечаниях к выпуску v1.1:

Добавлена ​​поддержка UTF-8 кодировкой не-ASCII символов при кодировании и декодировании JavaScript строки PKCS1.

PKCS # 1 обивка в v1.0 является:

// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint 
function pkcs1pad2(s, n) { 
    if (n < s.length + 11) { 
     alert("Message too long for RSA"); 
     return null; 
    } 
    var ba = new Array(); 
    var i = s.length - 1; 
    while (i >= 0 && n > 0) ba[--n] = s.charCodeAt(i--); 
    ba[--n] = 0; 
    var rng = new SecureRandom(); 
    ... 
    return new BigInteger(ba); 
} 

Функция обивка PKCS # 1 в версии 1.1 и более поздней версии:

// PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint 
function pkcs1pad2(s,n) { 
    if(n < s.length + 11) { // TODO: fix for utf-8 
    console.error("Message too long for RSA"); 
    return null; 
    } 
    var ba = new Array(); 
    var i = s.length - 1; 
    while(i >= 0 && n > 0) { 
    var c = s.charCodeAt(i--); 
    if(c < 128) { // encode using utf-8 
     ba[--n] = c; 
    } 
    else if((c > 127) && (c < 2048)) { 
     ba[--n] = (c & 63) | 128; 
     ba[--n] = (c >> 6) | 192; 
    } 
    else { 
     ba[--n] = (c & 63) | 128; 
     ba[--n] = ((c >> 6) & 63) | 128; 
     ba[--n] = (c >> 12) | 224; 
    } 
    } 
    ba[--n] = 0; 
    ... 
    return new BigInteger(ba); 
} 

rsa.js v1.0 обрабатывал каждый символ как 1-байтовый символ. Поскольку символы v1.1 тестируются, чтобы узнать, являются ли они многобайтными utf-8 или нет.

Кажется, только мои варианты либо:

  1. Палка с rsa.js v1.0
  2. Создать модифицированную версию rsa.js (и rsa2.js), которые позволяют мне отключить в Обнаружение символов utf-8.
  3. (Отредактировано) Изменить код для использования defensivejs.com, который поддерживает PKCS # 1 v2 (oaep).

Идеи?

+0

Интересно, могут быть различия в версии PKCS, которые могут вызвать много головных болей. Я бы настоятельно рекомендовал вместо этого использовать эту библиотеку [Стэнфордский JavaScript Crypto Library] (https://github.com/bitwiseshiftleft/sjcl) вместо этой библиотеки, потому что я знаю, что SJCL более широко используется и тестируется. – TheGreatContini

+0

Да, довольно уверен, что библиотека Ву внедряет [PCKS # 1 v1.5] (https://tools.ietf.org/html/rfc2313), которая может быть уязвима для атаки Bleichenbacher. Как криптограф, я рекомендую не использовать этот код! Вместо этого используйте SJCL! – TheGreatContini

ответ

3
  1. Этот код реализует дополнение PKCS # 1 v1.5 в обоих случаях, единственное отличие - поддержка utf-8. Чтобы он работал с библиотекой-получателем, эта библиотека должна будет декодировать контент так же, как он его кодирует. Удачи вам в этом, я не думаю, что вы найдете что-нибудь, что делает это.

  2. PKCS # 1 v1.5 padding - insecure из-за нападения, проиллюстрированного Даниэлем Блейхенбахером в 1999 году. В настоящее время рекомендуется использовать PKCS # 1 v2.x. Код Wu не поддерживает это.

  3. Если вы действительно хотите использовать эту библиотеку (я рекомендую против него), вероятно, самый чистый подход для отправки в ключевом шестнадцатеричном, прежде чем зашифровать его («E0F8AD4092F81FC401E60ECB7F5B8F1A») и убедитесь, что шестигранный получатель декодирует его после Расшифровать : это будет работать с настройками UUF-8 Wu. Вы также можете использовать кодировку/декодирование base64.

  4. SJCL - это гораздо лучшая библиотека криптовалеев JavaScript, и вы вряд ли столкнетесь с такими проблемами. Насколько мне известно, код Wu был разработан как PoC его замечательного протокола аутентификации, тогда как SJCL предназначен для более общего использования и поддерживается сообществом.

+0

К сожалению, похоже, что библиотека SJCL не поддерживает RSA. RSA является требованием, поскольку дешифрующим устройством является Thales HSM Payshield 9000 (https://en.wikipedia.org/wiki/Hardware_security_module). HSM поддерживает PKCS # 1 v2 (OEAP) – andyvan

+0

В текущей реализации используется только пара открытого/закрытого ключа. Как только сервер получает запрос, информация обрабатывается (успех или сбой), а затем ключи стираются и не используются повторно. Исходя из этого варианта использования, я бы предположил, что атака CCA Bleichenbacher не применима, например. у злоумышленника нет возможности повторять запросы со случайными данными. – andyvan

+0

@andyvan святой поэт бэтмен, вы правы! Неудовлетворительно! Вы также можете рассмотреть библиотеку Google, но не знаете, как сложно работать или насколько она зрелая, см .: https://github.com/google/end-to-end/blob/master/src/javascript /crypto/e2e/asymmetric/rsa.js. Если ключи стираются при сбое, нажмите. Вы правы, что атака не будет применяться. – TheGreatContini

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