如何使用JSBN加密Crypto-JS密钥? [英] How do I encrypt Crypto-JS keys with JSBN?

查看:356
本文介绍了如何使用JSBN加密Crypto-JS密钥?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 JSBN 来使用公共加密/解密数据/私人密钥对。

I'm using JSBN to encrypt/decrypt data using public/private keypairs. It works great for text data, including hex strings.

我的问题是我现在有二进制数据,特别是 Crypto-JS 字数组,我需要使用公共密钥进行加密并发送到另一个平台。

My problem is now I have binary data, specifically Crypto-JS Word Arrays, that I need to encrypt with a public key and send along to another platform.

因此,请考虑以下问题:

So consider this:

var key = CryptoJS.lib.WordArray.random(256/8);
var rsa = new RSAKey();
rsa.setPublic(modulus, exponent);
var encrypted_key = rsa.encrypt(key.toString());

此方法有效,但这意味着'encrypted_key'实际上是已加密的十六进制字符串,而不是实际的密钥。我需要加密实际的密钥。

This works but it means 'encrypted_key' is infact a hex string that's been encrypted, not the actual key. I need to encrypt the actual key.

所以我在这里看到了两个挑战:

So I see two challenges here:

1)我不是100%地确定如何从CryptoJS.lib.WordArray中获取实际的字节-尽管这似乎并不是完全无法克服的。

1) I'm not 100% sure how to get the actual bytes out of a CryptoJS.lib.WordArray -- though that doesn't seem totally insurmountable.

2)我不知道如果甚至可以使用JSBN加密二进制数据。我很乐意指出如何做到这一点。

2) I have no idea if it's even possible to encrypt binary data using JSBN. I'd love pointers to figure out how to do it.

有什么想法吗?

推荐答案

JSBN库包含一个函数pkcs1pad2(),其中它使用JavaScript的charCodeAt()函数将文本转换为数值。您将在第一个while()循环中看到该转换代码:

The JSBN library contains a function, namely pkcs1pad2(), wherein it converts the text to numeric values using JavaScript's charCodeAt() function. You'll see that conversion code in the first while() loop:

function pkcs1pad2(s,n) {
  if(n < s.length + 11) { // TODO: fix for utf-8
    alert("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;
  var rng = new SecureRandom();
  var x = new Array();
  while(n > 2) { // random non-zero pad
    x[0] = 0;
    while(x[0] == 0) rng.nextBytes(x);
    ba[--n] = x[0];
  }
  ba[--n] = 2;
  ba[--n] = 0;
  return new BigInteger(ba);
}

如果您希望加密二进制数据,则可能需要修改它函数,以便按所需方式转换输入。

If you wish to encrypt binary data then you'll likely have to modify this function so it converts the input in the way you want it.

下面是pkcs1pad2()的示例,该示例经过修改以接受十六进制字符串形式的二进制数据。如果使用此版本的pkcs1pad2(),则可以将CryptoJS.lib.WordArray转换为十六进制并将该十六进制字符串传递给rsa.encrypt()。

Below is an example of pkcs1pad2() modified to accept binary data in the form of a hex string. If you use this version of pkcs1pad2() then you can convert your CryptoJS.lib.WordArray into hex and pass that hex string to rsa.encrypt().

function pkcs1pad2(hexPlaintext,n) {
  if(n < hexPlaintext.length/2 + 11) {
    alert("Message too long for RSA");
    return null;
  }
  var ba = new Array();
  var i = hexPlaintext.length;
  while(i >= 2 && n > 0) {
    ba[--n] = parseInt(hexPlaintext.slice(i-2,i),16);
    i-=2;
  }
  ba[--n] = 0;
  var rng = new SecureRandom();
  var x = new Array();
  while(n > 2) { // random non-zero pad
    x[0] = 0;
    while(x[0] == 0) rng.nextBytes(x);
    ba[--n] = x[0];
  }
  ba[--n] = 2;
  ba[--n] = 0;
  return new BigInteger(ba);
}

或者,您可以对其进行修改以直接使用WordArray并将其转换为JSBN使用的数组格式,但我将其留给读者练习。

Alternatively, you could modify it to take the WordArray directly and convert that to the array format that is used by JSBN, but I'll leave that as an exercise for the reader.

这篇关于如何使用JSBN加密Crypto-JS密钥?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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