2015-11-04 4 views
1

Цель этого не очень важна для безопасности, и ключ будет длинным, поэтому я просто хочу использовать простое шифрование XOR для строк.Просто XOR шифрует в Javascript и расшифровывает в Java

Ну, Javascript на клиенте выглядит следующим образом:

function dc_encrypt(str, key) 
{ 
    var ord = []; var res = ""; 

    var i; 
    for (i = 1; i <= 255; i++) {ord[String.fromCharCode(i)] = i} 

    for (i = 0; i < str.length; i++) 
     res += String.fromCharCode(ord[str.substr(i, 1)]^ord[key.substr(i % key.length, 1)]); 

    return(res); 
} 

И Ява является:

public String dc_decrypt(String str, String key) 
{ 
    StringBuilder sb = new StringBuilder(); 
    for(int i = 0; i < str.length(); i++) 
    sb.append((char)(str.charAt(i)^key.charAt(i % (key.length())))); 
    return(sb.toString()); 
} 

К сожалению, это производит некоторые очень странные результаты. Некоторые буквы различаются после шифрования в JS, отправки результата через POST и дешифрования на Java. В каждом случае это не кажется надежным.

Я предполагаю, что проблема должна иметь какое-то отношение к кодированию ... кто-то знает более надежное решение для этого?

Огромное спасибо заранее! :)

+0

Можете ли вы предоставить образец ввода и разные выходы в двух реализациях? – RealSkeptic

+0

Попробуйте кодировать ваш зашифрованный вывод с помощью Base64, а затем декодировать его на Java –

ответ

1

Когда XOR-кодирование двух строк, полученные XOR-значения отдельных символов иногда не приводят к символам, которые могут отображаться. Поэтому одним из решений является кодирование результата в виде последовательности шестнадцатеричных значений, а затем для декодирования этих шестнадцатеричных значений на стороне сервера.

Javascript:

function encryptStringWithXORtoHex(input,key) { 
    var c = ''; 
    while (key.length < input.length) { 
     key += key; 
    } 
    for(var i=0; i<input.length; i++) { 
     var value1 = input[i].charCodeAt(0); 
     var value2 = key[i].charCodeAt(0); 

     var xorValue = value1^value2; 

     var xorValueAsHexString = xorValue.toString("16"); 

     if (xorValueAsHexString.length < 2) { 
      xorValueAsHexString = "0" + xorValueAsHexString; 
     } 

     c += xorValueAsHexString; 
    } 
    return c; 
} 

Java-код:

private static String decryptStringWithXORFromHex(String input,String key) { 
    StringBuilder c = new StringBuilder(); 
    while (key.length() < input.length()/2) { 
     key += key; 
    } 

    for (int i=0;i<input.length();i+=2) { 
     String hexValueString = input.substring(i, i+2); 
     int value1 = Integer.parseInt(hexValueString, 16); 
     int value2 = key.charAt(i/2); 

     int xorValue = value1^value2; 

     c.append(Character.toString((char) xorValue)); 

    } 
    return c.toString(); 
}; 

Пример: Encode в Javascript:

encryptStringWithXORtoHex('Encrypt This','SecretKey');

возвращает строку 160b00001c043f452d3b0c10

Дешифровка в Java:

decryptStringWithXORFromHex("160b00001c043f452d3b0c10","SecretKey")

возвращает Encrypt This

Обратите внимание: показано решение работает только для символов, которые имеют значение charChode меньше или равно 255. Если вы хотите использовать решение для символов Unicode (например, €) вам придется изменить код, чтобы позаботиться об этом.