javascript中的RSA不再支持ASCII /字节数组 [英] RSA in javascript no longer supports ASCII/byte arrays

查看:368
本文介绍了javascript中的RSA不再支持ASCII /字节数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的是rsa.js v1.0,从 http:// www- cs-students.stanford.edu/~tjw/jsbn/ 来加密浏览器中的ASCII字符串。该字符串实际上是一个16字节的数组,包含一个双长度的TripleDes键。使用rsa v1.0这个功能。字节数组在服务器上正确解密(使用Bouncy Castle或Thales HSM)作为16字节数组。

I am using rsa.js v1.0 from http://www-cs-students.stanford.edu/~tjw/jsbn/ to encrypt an ASCII string in a browser. The string is actually a 16 byte array that contains a double-length TripleDes key. With rsa v1.0 this works. The byte array is correctly decrypted on the server (using Bouncy Castle or a Thales HSM) as a 16 byte array.

例如

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城​​堡解密数据,而不是一个16字节的数组,现在是一个25字节的数组。

When moving the rsa.js v1.4 this not longer works. Bouncy castle decrypts the data, but instead of a 16 byte array, it is now a 25 byte array.

我在rsa.js库中可以看到的关键区别是在v1.1发行说明中:

The key difference I can see in the rsa.js library is in the v1.1 release notes:

当PKCS1编码和解码JavaScript字符串时,增加了对非ASCII字符的utf-8编码的支持。

v1.0中的PKCS#1填充是:

The PKCS#1 padding in v1.0 is:

// 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);
}

v1.1及更高版本中的PKCS#1填充功能是: p>

The PKCS#1 padding function in v1.1 and later is:

// 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 treated each character as a 1 byte character. Since v1.1 characters are tested to see if they are multi-byte utf-8 or not.

似乎我唯一的选择是:


  1. 坚持使用rsa。 js v1.0

  2. 创建允许我禁用utf-8字符检测的rsa.js(和rsa2.js)的修改版本。 (编辑)更改代码以使用支持PKCS#1 v2(oaep)的defensivejs.com。

想法?

推荐答案


  1. 此代码正在实现PKCS#1 v1。在这两种情况下,填充都是utf-8的唯一区别。为了与收件人库一起工作,该库需要以与编码内容相同的方式对内容进行解码。祝你好运,我不认为你会发现任何事情。

  1. This code is implementing PKCS #1 v1.5 padding in both cases, the only difference is the utf-8 support. For it to work with a recipient library, that library would need to decode the content the same way he encodes it. Good luck on that, I don't think you will find anything that does that.

PKCS#1 v1.5填充是不安全,由于Daniel Bleichenbacher 1999年左右所发生的攻击。现在建议使用PKCS#1 v2.x.吴的代码不支持这个。

PKCS #1 v1.5 padding is insecure due to an attack illustrated by Daniel Bleichenbacher around 1999. Nowadays it is recommended to use PKCS #1 v2.x. Wu's code does not support this.

如果你真的想使用这个库(我建议反对它),可能最干净的方法是发送密钥十进制编码后加密(E0F8AD4092F81FC401E60ECB7F5B8F1A),并确保收件人十六进制解密后解密:这可以解决吴的UTF-8调整。您也可以使用base64编码/解码。

If you really wanted to use this library (I recommend against it), probably the cleanest approach is to send in the key hex encoded before you encrypt it ("E0F8AD4092F81FC401E60ECB7F5B8F1A") and make sure recipient hex decodes it after decrypt: that would work around Wu's UTF-8 adjustments. You could also use base64 encoding/decoding.

SJCL是一个更好的JavaScript加密库,您不太会遇到这样的问题。据我所知,吴的代码被设计为他的精美身份验证协议的PoC,而SJCL则是为了更普遍的使用而设计,并由社区维护。

SJCL is a much better JavaScript crypto library, and you will unlikely run into problems like this. To my knowledge, Wu's code was designed as a PoC of his wonderful authentication protocol, whereas SJCL is designed for more general use and is being maintained by a community.

这篇关于javascript中的RSA不再支持ASCII /字节数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆