Javascript 如何使用JSBN加密加密JS密钥?

Javascript 如何使用JSBN加密加密JS密钥?,javascript,rsa,cryptojs,jsbn,Javascript,Rsa,Cryptojs,Jsbn,我正在使用公钥/私钥对加密/解密数据。它适用于文本数据,包括十六进制字符串 我的问题是现在我有二进制数据,特别是单词数组,我需要用公钥加密并发送到另一个平台 请考虑这个: var key = CryptoJS.lib.WordArray.random(256/8); var rsa = new RSAKey(); rsa.setPublic(modulus, exponent); var encrypted_key = rsa.encrypt(key.toString()); 这是可行的,但它

我正在使用公钥/私钥对加密/解密数据。它适用于文本数据,包括十六进制字符串

我的问题是现在我有二进制数据,特别是单词数组,我需要用公钥加密并发送到另一个平台

请考虑这个:

var key = CryptoJS.lib.WordArray.random(256/8);
var rsa = new RSAKey();
rsa.setPublic(modulus, exponent);
var encrypted_key = rsa.encrypt(key.toString());
这是可行的,但它意味着“加密密钥”实际上是一个已加密的十六进制字符串,而不是实际密钥。我需要加密实际的密钥

因此,我在这里看到两个挑战:

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

2) 我不知道是否有可能使用JSBN加密二进制数据。我很想知道怎么做


有什么想法吗?

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

函数pkcs1pad2(s,n){ 如果(n=0&&n>0){ var c=s.charCodeAt(i--); 如果(c<128){//使用utf-8编码 ba[--n]=c; } 否则如果((c>127)和((c<2048)){ ba[--n]=(c&63)| 128; ba[--n]=(c>>6)| 192; } 否则{ 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=新数组(); 而(n>2){//随机非零pad x[0]=0; 而(x[0]==0)个字节(x); ba[--n]=x[0]; } ba[--n]=2; ba[--n]=0; 返回新的BigInteger(ba); } 如果您希望加密二进制数据,则可能必须修改此函数,以便它以您希望的方式转换输入

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

函数pkcs1pad2(十六进制明文,n){ if(n=2&&n>0){ ba[--n]=parseInt(hexplantext.slice(i-2,i),16); i-=2; } ba[--n]=0; var rng=new SecureRandom(); var x=新数组(); 而(n>2){//随机非零pad x[0]=0; 而(x[0]==0)个字节(x); ba[--n]=x[0]; } ba[--n]=2; ba[--n]=0; 返回新的BigInteger(ba); }
或者,您可以修改它以直接获取WordArray并将其转换为JSBN使用的数组格式,但我将把它作为练习留给读者。

从javascript转换为java的pkcs1pad2函数:

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

    if(keysize < data.length()+11)
        return null;

    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;

    return new BigInteger(buffer);
}
和Helper.HexToBytes:

 public static byte[] hexToBytes(char[] hex)throws IllegalArgumentException{
     byte[] data = new byte[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))
             throw new IllegalArgumentException();
         data[j] = (byte) (hi << 4 | lo);
     }
     return data;
 }
public static byte[]hexToBytes(char[]hex)抛出IllegalArgumentException{
字节[]数据=新字节[hex.length/2];
对于(int i=0,j=0;jdata[j]=(byte)(嗨!当然,另一端——pkcs1unpad2——也需要进行类似的修改(或扩展)。
public BigInteger pkcs1pad2(String data,int keysize){
    byte[] buffer=new byte[keysize];
    Random rg=new Random();

    if(keysize < data.length()+11)
        return null;

    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;

    return new BigInteger(buffer);
}
//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=new BigInteger(exp);
    BigInteger modB=new BigInteger(mod);

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

    byte[] encoding = (new Base64()).encode(Helper.hexToBytes(data3.toString(16).toCharArray()));
    return new String(encoding, "US-ASCII");
}
 public static byte[] hexToBytes(char[] hex)throws IllegalArgumentException{
     byte[] data = new byte[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))
             throw new IllegalArgumentException();
         data[j] = (byte) (hi << 4 | lo);
     }
     return data;
 }