Я использую 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 или нет.
Кажется, только мои варианты либо:
- Палка с rsa.js v1.0
- Создать модифицированную версию rsa.js (и rsa2.js), которые позволяют мне отключить в Обнаружение символов utf-8.
- (Отредактировано) Изменить код для использования defensivejs.com, который поддерживает PKCS # 1 v2 (oaep).
Идеи?
Интересно, могут быть различия в версии PKCS, которые могут вызвать много головных болей. Я бы настоятельно рекомендовал вместо этого использовать эту библиотеку [Стэнфордский JavaScript Crypto Library] (https://github.com/bitwiseshiftleft/sjcl) вместо этой библиотеки, потому что я знаю, что SJCL более широко используется и тестируется. – TheGreatContini
Да, довольно уверен, что библиотека Ву внедряет [PCKS # 1 v1.5] (https://tools.ietf.org/html/rfc2313), которая может быть уязвима для атаки Bleichenbacher. Как криптограф, я рекомендую не использовать этот код! Вместо этого используйте SJCL! – TheGreatContini