2014-12-05 51 views
0

我的Liferay 5.2 ANS ExtJS的工作3.4加密网址查询参数

我在参数传入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(); 
      } 
     } 
    } 

这是我的网址,其产生:

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

更新时间:

我用SHA1功能,在我的网址我有这样的变化:

VAR 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); 

的parametre将这样产生:

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 2014-12-05 10:26:41

+0

谢谢你的回应,我已经更新了我的问题,我仍然有问题解密生成的密钥 – franco 2014-12-05 10:51:36

+0

不,这不是哈希值的工作原理。你不解密或加密。您根据您希望查看的参数计算您的末端哈希,并检查它是否与您收到的参数的哈希匹配 – fge 2014-12-05 10:52:49

回答

1

加密和其他技术,如互助,你需要在客户端上的一个键。由于客户端代码是可以自由显示的(毕竟它是JavaScript),所以无法有效隐藏密钥。因此用户可以查看代码并基于它创建一个有效的URL。


您不需要加密,因为参数似乎不是机密的。你只需要一个消息认证码(MAC)。这意味着你凑,你想验证像yearDec一些秘密,是已知的客户端和服务器(带有可选的盐)的数量:

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

注意|意味着字节数组或字符串的串联。现在您生成的网址为yearDechYearDec。这两个参数都发送到服务器。服务器可以通过运行与上面相同的散列函数来检查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),这需要花费很长时间超过五分钟我使用的是Firefox的 – franco 2014-12-06 13:41:14

+0

。大约需要一秒钟。你可以减少迭代。我实际上停止使用Chrome,因为它太慢了。 – 2014-12-06 13:46:50

+0

好吧,我不能重现你的问题。在Win7 32位上,Chrome 39上的时间不到一秒钟。 – 2014-12-06 14:17:03