2014-12-05 2 views
0

я работаю с Liferay 5.2 ANS ExtJS 3.4Шифровать Параметры URL запроса

У меня есть проблема в передаче параметров в URL У меня есть отчеты, которые создаются с помощью параметров, передаваемых в URL но проблема в том, что мы может внести ручное изменение в эти параметры, поэтому в это время будет создан другой отчет, который запрещен. моя цель - найти решение для шифрования этих параметров , а в классе java мы расшифруем эти параметры для генерации отчетов. Так что в этом случае параметры остаются неизменными даже при внесении ручного изменения в URL. Итак, мы сделаем шифрование во время вызова этого URL (в javascript) и дешифрования в java для чтения параметров. , но я думаю, что мы должны сделать уникальный ключ в обоих зашифрованы и расшифрованы параметры

это мой код:

в JavaScript:

var numDec = numDec_decsion.getValue();  

var yearDec = yearCorresp_decsion.getValue();  

    var url = "<c:url value='/printer'/>?method=genreport&numDec="+ numDec + 
         "&yearDec=" + yearDec ; 
       window.open(url); 

это код Java:

public void createReport(HttpServletRequest request, 
HttpServletResponse response) throws Exception { 

try { 
    ServletContext context = request.getSession().getServletContext(); 
    String contextPath = context.getRealPath("/"); 
    contextPath += ((contextPath.endsWith("/") || 
    contextPath.endsWith("\\")) ? "" : "/");   
    String root_dir = contextPath + "WEB-INF\\Template\\report\\"; 
    String reportFile = root_dir + request.getParameter("report") + 
     ".jasper";   
    ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(context); 
    Connection connection = getSession(appContext).connection(); 
    Map parameters = new HashMap(); 
    Iterator iter = request.getParameterMap().keySet().iterator();   
    while (iter.hasNext()) { 
     String paramName = (String) iter.next(); 
     parameters.put(paramName, request.getParameter(paramName)); 
     System.out.println(paramName + ":"+request.getParameter(paramName)); 
    } 
    parameters.put("root_dir", root_dir); 
    createPDFReport(response, reportFile, parameters, connection); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

}

public void createPDFReport(HttpServletResponse response, 
     String reportFile, Map parameters, Connection connection) { 


     byte[] bytes = null; 

     try { 
      System.out.println("-------start run report-------"); 
      bytes = JasperRunManager.runReportToPdf(reportFile, parameters, 
        connection); 
     } catch (JRException e) { 
      e.printStackTrace(); 
     } 



     if ((bytes != null) && (bytes.length > 0)) { 
      response.setContentType("application/pdf"); 
      response.setContentLength(bytes.length); 

      try { 
       ServletOutputStream ouputStream = response.getOutputStream(); 
       ouputStream.write(bytes, 0, bytes.length); 
       ouputStream.flush(); 
       ouputStream.close(); 
      } catch (IOException e1) { 
       e1.printStackTrace(); 
      } 
     } 
    } 

это мой URL, который генерируется:

http://com.supcom:8080/SupCom/printer?method=genreport&numDec=265&yearDec=1435 

Обновлено:

Я использую SHA1 функции и в моем URL я сделать это изменение:

вар numDec = numDec_decsion. GetValue();

var yearDec = yearCorresp_decsion.getValue();  

    var url = "<c:url value='/printer'/>?method=genreport&numDec="+ SHA1(numDec) + 
         "&yearDec=" + yearDec ; 
       window.open(url); 

параметр будет генерироваться следующим образом:

http://com.supcom:8080/SupCom/printer?method=genreport&numDec=6216f8a75fd5bb3d5f22b6f9958cdede3fc086c2&yearDec=1435

, но я не нашел способ сделать дешифрования в Java класса обычно в методом createReport

это код SHA1

/** 
* Secure Hash Algorithm (SHA1) 
* http://www.webtoolkit.info/ 
**/ 
function SHA1(msg) { 
    function rotate_left(n,s) { 
    var t4 = (n<<s) | (n>>>(32-s)); 
    return t4; 
    }; 
    function lsb_hex(val) { 
    var str=""; 
    var i; 
    var vh; 
    var vl; 
    for(i=0; i<=6; i+=2) { 
     vh = (val>>>(i*4+4))&0x0f; 
     vl = (val>>>(i*4))&0x0f; 
     str += vh.toString(16) + vl.toString(16); 
    } 
    return str; 
    }; 
    function cvt_hex(val) { 
    var str=""; 
    var i; 
    var v; 
    for(i=7; i>=0; i--) { 
     v = (val>>>(i*4))&0x0f; 
     str += v.toString(16); 
    } 
    return str; 
    }; 
    function Utf8Encode(string) { 
    string = string.replace(/\r\n/g,"\n"); 
    var utftext = ""; 
    for (var n = 0; n < string.length; n++) { 
     var c = string.charCodeAt(n); 
     if (c < 128) { 
     utftext += String.fromCharCode(c); 
     } 
     else if((c > 127) && (c < 2048)) { 
     utftext += String.fromCharCode((c >> 6) | 192); 
     utftext += String.fromCharCode((c & 63) | 128); 
     } 
     else { 
     utftext += String.fromCharCode((c >> 12) | 224); 
     utftext += String.fromCharCode(((c >> 6) & 63) | 128); 
     utftext += String.fromCharCode((c & 63) | 128); 
     } 
    } 
    return utftext; 
    }; 
    var blockstart; 
    var i, j; 
    var W = new Array(80); 
    var H0 = 0x67452301; 
    var H1 = 0xEFCDAB89; 
    var H2 = 0x98BADCFE; 
    var H3 = 0x10325476; 
    var H4 = 0xC3D2E1F0; 
    var A, B, C, D, E; 
    var temp; 
    msg = Utf8Encode(msg); 
    var msg_len = msg.length; 
    var word_array = new Array(); 
    for(i=0; i<msg_len-3; i+=4) { 
    j = msg.charCodeAt(i)<<24 | msg.charCodeAt(i+1)<<16 | 
    msg.charCodeAt(i+2)<<8 | msg.charCodeAt(i+3); 
    word_array.push(j); 
    } 
    switch(msg_len % 4) { 
    case 0: 
     i = 0x080000000; 
    break; 
    case 1: 
     i = msg.charCodeAt(msg_len-1)<<24 | 0x0800000; 
    break; 
    case 2: 
     i = msg.charCodeAt(msg_len-2)<<24 | msg.charCodeAt(msg_len-1)<<16 | 0x08000; 
    break; 
    case 3: 
     i = msg.charCodeAt(msg_len-3)<<24 | msg.charCodeAt(msg_len-2)<<16 | msg.charCodeAt(msg_len-1)<<8 | 0x80; 
    break; 
    } 
    word_array.push(i); 
    while((word_array.length % 16) != 14) word_array.push(0); 
    word_array.push(msg_len>>>29); 
    word_array.push((msg_len<<3)&0x0ffffffff); 
    for (blockstart=0; blockstart<word_array.length; blockstart+=16) { 
    for(i=0; i<16; i++) W[i] = word_array[blockstart+i]; 
    for(i=16; i<=79; i++) W[i] = rotate_left(W[i-3]^W[i-8]^W[i-14]^W[i-16], 1); 
    A = H0; 
    B = H1; 
    C = H2; 
    D = H3; 
    E = H4; 
    for(i= 0; i<=19; i++) { 
     temp = (rotate_left(A,5) + ((B&C) | (~B&D)) + E + W[i] + 0x5A827999) & 0x0ffffffff; 
     E = D; 
     D = C; 
     C = rotate_left(B,30); 
     B = A; 
     A = temp; 
    } 
    for(i=20; i<=39; i++) { 
     temp = (rotate_left(A,5) + (B^C^D) + E + W[i] + 0x6ED9EBA1) & 0x0ffffffff; 
     E = D; 
     D = C; 
     C = rotate_left(B,30); 
     B = A; 
     A = temp; 
    } 
    for(i=40; i<=59; i++) { 
     temp = (rotate_left(A,5) + ((B&C) | (B&D) | (C&D)) + E + W[i] + 0x8F1BBCDC) & 0x0ffffffff; 
     E = D; 
     D = C; 
     C = rotate_left(B,30); 
     B = A; 
     A = temp; 
    } 
    for(i=60; i<=79; i++) { 
     temp = (rotate_left(A,5) + (B^C^D) + E + W[i] + 0xCA62C1D6) & 0x0ffffffff; 
     E = D; 
     D = C; 
     C = rotate_left(B,30); 
     B = A; 
     A = temp; 
    } 
    H0 = (H0 + A) & 0x0ffffffff; 
    H1 = (H1 + B) & 0x0ffffffff; 
    H2 = (H2 + C) & 0x0ffffffff; 
    H3 = (H3 + D) & 0x0ffffffff; 
    H4 = (H4 + E) & 0x0ffffffff; 
    } 
    var temp = cvt_hex(H0) + cvt_hex(H1) + cvt_hex(H2) + cvt_hex(H3) + cvt_hex(H4); 

    return temp.toLowerCase(); 
} 
+0

Почему бы вам не использовать хэш вместо этого, который вы добавляете в запрос параметры? Хэш SHA1, например, – fge

+0

Спасибо за ваш ответ, я обновил свой вопрос, у меня все еще есть проблема с расшифровкой генерируемого ключа – franco

+0

Нет, это не так, как работает хеш. Вы не расшифровываете и не шифруете. Вы вычисляете хэш на своем конце из параметров _you_ хотите видеть, и вы проверяете, что он соответствует хешу параметров, которые вы получаете – fge

ответ

1

Для шифрования и других методов, таких как MAC, вам нужен ключ на клиенте. Так как код клиента свободно виден (в конце концов, это JavaScript), вы не можете эффективно скрыть ключ. Таким образом, пользователь может просмотреть код и создать на нем действительный URL.

Для этого не требуется шифрование, поскольку параметры не являются конфиденциальными. Вам просто нужен код аутентификации сообщения (MAC).Это означает, что вы хеширования номер, который вы хотите аутентификацией как yearDec с какой-то секрет, который, как известно, клиент и сервер (с дополнительной соли):

hYearDec = HASH(HASH(yearDec | key) | key [| salt]) 

Обратите внимание, что | означает конкатенацию байтового массива или строки. Теперь вы создаете URL-адрес с yearDecиhYearDec. Оба параметра отправляются на сервер. Сервер может проверить, что yearDec не был изменен, запустив ту же функцию хэша, что и выше, потому что ключ предположительно является секретным для клиента и сервера. Значение соли также необходимо отправить на сервер, поскольку оно не является секретным.

Обратите внимание, что если вы зашифруете значения, вам все равно потребуется некоторая проверка целостности, как MAC.

Хотя любая функция хеш-функции, такая как SHA1, вы должны использовать PBKDF2 для получения MAC на основе данных, потому что ее значительно сложнее разбить.

CryptoJS предоставляет appropriate functions для этого.

var secretKey = "someSecretRandomString_k345kretiu46kzjnh"; 
var requestParameters = "yearDec=123456"; // send this 
var salt = CryptoJS.lib.WordArray.random(128/8); 
var key = CryptoJS.PBKDF2(requestParameters+secretKey, salt, { keySize: 256/32, iterations: 500 }); 
var saltHex = salt.toString(); // send this 
var macHex = key.toString() // send this 

А на сервере:

String plaintext = "yearDec=123456"; // request parameter 
String secretKey = "someSecretRandomString_k345kretiu46kzjnh"; 
plaintext += secretKey; // add key in the same way as in the client 
char[] plaintextChars = new char[plaintext.length()]; 
plaintext.getChars(0, plaintext.length(), plaintextChars, 0); 
int keySize = 256; // during the system setup 
int iterations = 500; // during the system setup 
String macHex = "bf92577e37627dbdc4a67510510c130aca6cf8e2e8bed0ea218f6cd909e3270d"; // further request parameters 
String saltHex = "639a8d66d6a4fac8a39ce7c8b42fe0d8"; // further request parameters 

// convert 
byte[] mac = hexStringToByteArray(macHex); 
byte[] salt = hexStringToByteArray(saltHex); 

// derive 
SecretKeyFactory f = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); 
KeySpec ks = new PBEKeySpec(plaintextChars, salt, iterations, keySize); 
SecretKey s = f.generateSecret(ks); 

// check 
Arrays.equals(s.getEncoded(), mac); 

я использую this преобразовать шестнадцатеричный в байтовые массивы:

public static byte[] hexStringToByteArray(String s) { 
    int len = s.length(); 
    byte[] data = new byte[len/2]; 
    for (int i = 0; i < len; i += 2) { 
     data[i/2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) 
       + Character.digit(s.charAt(i+1), 16)); 
    } 
    return data; 
} 
+0

Благодарим вас за ответ, но у меня возникла проблема с генерацией ключа (key512Bits1000Iterations), это занимает много времени более пяти минут. – franco

+0

Я использую Firefox. Это занимает около секунды. Вы можете уменьшить итерации. Я фактически прекратил использовать Chrome, потому что он был слишком медленным. –

+0

Хорошо, я не могу воспроизвести вашу проблему. Это занимает менее секунды на Chrome 39 на Win7 32-бит. –

Смежные вопросы