Skip to content Skip to sidebar Skip to footer

How Do I Encrypt Crypto-js Keys With Jsbn?

I'm using JSBN to encrypt/decrypt data using public/private keypairs. It works great for text data, including hex strings. My problem is now I have binary data, specifically Crypt

Solution 1:

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:

functionpkcs1pad2(s,n) {
  if(n < s.length + 11) { // TODO: fix for utf-8alert("Message too long for RSA");
    returnnull;
  }
  var ba = newArray();
  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;
    }
    elseif((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 = newSecureRandom();
  var x = newArray();
  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;
  returnnewBigInteger(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.

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().

functionpkcs1pad2(hexPlaintext,n) {
  if(n < hexPlaintext.length/2 + 11) {
    alert("Message too long for RSA");
    returnnull;
  }
  var ba = newArray();
  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 = newSecureRandom();
  var x = newArray();
  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;
  returnnewBigInteger(ba);
}

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.

Solution 2:

the pkcs1pad2 function converted from javascript to java:

public BigInteger pkcs1pad2(String data,int keysize){
    byte[] buffer=newbyte[keysize];
    Random rg=new Random();

    if(keysize < data.length()+11)
        returnnull;

    int i = data.length() - 1;
    while(i >= 0 && keysize > 0){
        --keysize;
        buffer[keysize] = (byte) data.charAt(i);
        i--;
    }
    --keysize;
    buffer[keysize] = 0;
    while(keysize > 2){
        --keysize;
        buffer[keysize] = (byte) (rg.nextInt(254)+1);
    }
    --keysize;
    buffer[keysize] = 2;
    --keysize;
    buffer[keysize] = 0;

    returnnew BigInteger(buffer);
}

the rsa encription:

http://hc.apache.org/downloads.cgi

//you need httpcomponents-client-4.3.1-bin.zip from apache.org//this contains working Base64 encoder!import org.apache.commons.codec.binary.Base64;
public String encrypt(String data,String modulus,String exponent)throws UnsupportedEncodingException{
    byte[] exp=Helper.hexToBytes(exponent.toCharArray());
    byte[] mod=Helper.hexToBytes(modulus.toCharArray());

    BigInteger expB=newBigInteger(exp);
    BigInteger modB=newBigInteger(mod);

    BigInteger data2=this.pkcs1pad2(data, (modB.bitLength()+7)>>3);
    BigInteger data3=data2.modPow(expB, modB);

    byte[] encoding = (newBase64()).encode(Helper.hexToBytes(data3.toString(16).toCharArray()));
    returnnewString(encoding, "US-ASCII");
}

and the Helper.HexToBytes:

publicstaticbyte[] hexToBytes(char[] hex)throws IllegalArgumentException{
     byte[] data = newbyte[hex.length / 2];
     for (int i = 0, j = 0; j < data.length; ++j){
         int hi = Character.digit(hex[i++], 16);
         int lo = Character.digit(hex[i++], 16);
         if ((hi < 0) || (lo < 0))
             thrownew IllegalArgumentException();
         data[j] = (byte) (hi << 4 | lo);
     }
     return data;
 }

Post a Comment for "How Do I Encrypt Crypto-js Keys With Jsbn?"