MD5 Signing HttpServletResponse

I am looking for a way to check the contents of an HttpServletResponse to sign them with an MD5 hash.

Pseudocode might look like this:

 process(Response response, Request request){ defaultProcessingFor(response,request); dispatcher.handle(response,request); // Here I want to read the contents of the Response object (now filled with data) to create a MD5 hash with them and add it to a header. } 

Is it possible?

+5
java servlets hash
Feb 02 2018-10-02T00
source share
3 answers

Yes it is possible. You need to decorate the answer with HttpServletResponseWrapper , in which you replace ServletOutputStream with a custom implementation that writes bytes to both the MD5 digest and the "source" output stream. Finally, provide an accessory to receive the final amount of MD5.

Update I just played around a bit, here is an example run:

Response Wrapper:

 public class MD5ServletResponse extends HttpServletResponseWrapper { private final MD5ServletOutputStream output; private final PrintWriter writer; public MD5ServletResponse(HttpServletResponse response) throws IOException { super(response); output = new MD5ServletOutputStream(response.getOutputStream()); writer = new PrintWriter(output, true); } public PrintWriter getWriter() throws IOException { return writer; } public ServletOutputStream getOutputStream() throws IOException { return output; } public byte[] getHash() { return output.getHash(); } } 

MD5 Output Stream:

 public class MD5ServletOutputStream extends ServletOutputStream { private final ServletOutputStream output; private final MessageDigest md5; { try { md5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { throw new ExceptionInInitializerError(e); } } public MD5ServletOutputStream(ServletOutputStream output) { this.output = output; } public void write(int i) throws IOException { byte[] b = { (byte) i }; md5.update(b); output.write(b, 0, 1); } public byte[] getHash() { return md5.digest(); } } 

How to use it:

 // Wrap original response with it: MD5ServletResponse md5response = new MD5ServletResponse(response); // Now just use md5response instead or response, eg: dispatcher.handle(request, md5response); // Then get the hash, eg: byte[] hash = md5response.getHash(); StringBuilder hashAsHexString = new StringBuilder(hash.length * 2); for (byte b : hash) { hashAsHexString.append(String.format("%02x", b)); } System.out.println(hashAsHexString); // Example af28cb895a479397f12083d1419d34e7. 
+6
Feb 02 '10 at 1:22
source

Technically, the term "signature" is reserved for, well, signatures and hash functions do not compute them.

To ensure that data has not been changed during the transfer, with a hash function, you must have a secure out-of-band way to transmit the hash value; adding a hash value to the HTTP headers will fail because anyone who can change the transmitted data can double-check the hash as desired and change the HTTP headers as they see fit.

With cryptography, you can "concentrate" on that secure out-of-band transmission in a reusable key. If the client and server have a common secret value unknown to the alleged attacker, then the acronym MAC, as in the "Message Authentication Code"; regular MAC HMAC .

In many practical situations, MAC cannot be used, because MAC requires a shared secret, and a secret that is shared too many times is no longer a secret. Each secret holder has the right to recount the MAC. If each client knows a secret, then in principle this is not a secret, and it can be safely assumed that the attacker also knows this. Therefore, you can go further and use digital signatures (real ones, those that use RSA, DSS, ECDSA ...), in which the server uses the private key (which only the server knows), and the clients only know about the corresponding public key. Knowledge of the public key is sufficient to verify signatures, but not to create new ones, and the private key cannot be overestimated from the public key (although they are mathematically related to each other). However, the introduction of a digital signature and its proper use is much more complicated than is usually accepted; it is best to use an already debugged protocol with existing implementations, and this protocol is called "SSL".

The fact is that without SSL, the likelihood that everything you do does not deter a certain attacker; it will just use processor cycles and network bandwidth and give you a warm fuzzy feel.

+1
Feb 02 '10 at 14:45
source

What are you trying to do?

You may be better off looking at the standard message format and wrap the contents of your reply in that message and sign it. OAuth comes to mind.

In addition, if you enable SSL, the client can be sure that the content of the response has not been changed.

0
Feb 02 '10 at 1:23
source



All Articles