Posting minutiae byte array from applet to server

In Grails web application, I am trying to post minutiae (finger print) byte array from applet to server using rest API.

This what i tried so for

private String post(String purl,String customerId, byte[] regMin1,byte[] regMin2) throws Exception {
    StringBuilder parameters = new StringBuilder();
    parameters.append("customerId=");
    parameters.append(customerId);
    parameters.append("&regMin1=");
    parameters.append(URLEncoder.encode(new String(regMin1),"UTF-8"));
    parameters.append("&regMin2=");
    parameters.append(URLEncoder.encode(new String(regMin2),"UTF-8"));
    URL url = new URL(purl); 
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();           
    connection.setDoOutput(true);
    connection.setDoInput(true);
    connection.setRequestMethod("POST"); 
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
    connection.setRequestProperty("Content-Length",Integer.toString(parameters.toString().getBytes().length));

    DataOutputStream wr = new DataOutputStream(connection.getOutputStream ());
    wr.writeBytes(parameters.toString());
    wr.flush();
    wr.close();
    BufferedReader in = new BufferedReader(new InputStreamReader(
                                connection.getInputStream()));
    StringBuilder builder = new StringBuilder();
    String aux = "";

    while ((aux = in.readLine()) != null) {
        builder.append(aux);
    }
    in.close();
    connection.disconnect();
    return builder.toString();
}   

I can post regMin1, regMin2 successfully but fingerprint verification always failing. I doubt, am i posting correctly.

Jon Skeet
people
quotationmark

This looks like a very bad idea to me:

parameters.append(URLEncoder.encode(new String(regMin1),"UTF-8"));
...
parameters.append(URLEncoder.encode(new String(regMin2),"UTF-8"));

If regMin1 and regMin2 aren't actually UTF-8 text (and my guess is that they're not) you'll almost certainly be losing data here.

Don't treat arbitrary binary data as if it's encoded text.

Instead, convert regMin1 and regMin2 to base64 - that way you'll end up with ASCII characters which you can then decode on the server to definitely get the original binary data. You can use a URL-safe version of base64 to avoid having to worry about further encoding the result.

There's a good public domain base64 library you can use for this if you don't have anything else to hand. So for example:

parameters.append("&regMin1=")
          .append(Base64.encodeBytes(regMin1, Base64.URL_SAFE))
          .append("&regMin2=")
          .append(Base64.encodeBytes(regMin2, Base64.URL_SAFE)); 

Note that you'd want to decode with the URL_SAFE option as well - don't just try to decode it as "normal" base64 data.

(You might still want to convert this to a POST request, and you'd definitely have an easier time if you could use a better HTTP library, but they're slightly separate concerns.)

people

See more on this question at Stackoverflow