我的servlet加密并发送HashMap及其MD5哈希。
然后客户端接收它们,并将MD5与从HashMap中运行的MD5进行比较。
这有时会起作用,但不会起作用,例如,如果HashMap是:
HashMap<String, Object> result = new HashMap<String, Object>();
result.put("error", 0);
result.put("coun", 0);
有效
但是,如果是:
HashMap<String, Object> result = new HashMap<String, Object>();
result.put("error", 0);
result.put("count", 0);
它不起作用 - 两个MD5哈希值不同。 (唯一不同的是关键'计数'而不是'国家')
程序发送类似的HashMaps,它们都包含只有字符串或整数的键/值,这是我第一次看到像这样的东西。
实际发送HashMap / MD5的详细信息 -
服务器确实:
//Work out MD5 of the HashMap result (convert it to bytes with objectOutputStream, and MD5 the bytes)
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
ObjectOutputStream out = new ObjectOutputStream(bos) ;
out.writeObject(result);
out.close();
byte[] md5 = messageDigest.digest(bos.toByteArray();
//Encrypt the httpURLConnection response stream, and send the HashMap result and the md5 over the stream
Cipher symmetricCipher = Cipher.getInstance("DES");
symmetricCipher.init(Cipher.ENCRYPT_MODE, symmetricKey);
CipherOutputStream cipherOutput = new CipherOutputStream(response.getOutputStream(), symmetricCipher);
BufferedOutputStream bufferedOutput = new BufferedOutputStream(cipherOutput);
ObjectOutputStream objectOutput = new ObjectOutputStream(out);
objectOutput.writeObject(result);
objectOutput.writeObject(md5);
objectOutput.flush();
客户做:
//Decrypt the httpURLConnection response stream
Cipher symmetricCipher = Cipher.getInstance("DES");
symmetricCipher.init(Cipher.DECRYPT_MODE, symmetricKey);
CipherInputStream cipherInput = new CipherInputStream(httpInput, symmetricCipher);
BufferedInputStream bufferedInput = new BufferedInputStream(cipherInput);
//read HashMap and MD5
ObjectInputStream objectInput = new ObjectInputStream(in);
HashMap<String, Object> result = (HashMap<String, Object>) objectInput.readObject();
byte[] hash1 = (byte[]) objectInput.readObject();
//workout hash of the Hashmap received.
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
ByteArrayOutputStream bos = new ByteArrayOutputStream() ;
ObjectOutputStream out = new ObjectOutputStream(bos) ;
out.writeObject(result);
out.close();
byte[] hash2 = messageDigest.digest(bos.toByteArray();
// Compare two hashes
if (!Arrays.equals(hash1, hash2)) {
System.out.println("Result received does not match hash, stopping list operation");
return;
}
使用相同类型的inputStream解密,以相同的方式计算出hashmap的md5,然后使用:
进行比较 if (!Arrays.equals(hash1, hash2)) {
System.out.println("Result received does not match hash, stopping get operation");
return;
}
我不明白为什么这对于发送我尝试过的所有HashMaps都有效,但现在这个计数键不起作用。 我已经测试过在客户端和servlet上比较HashMap中的各个键/值对,它们是相同的,但是在比较整个HashMap的两个MD5时它们是不匹配的。
另外,我不确定我是否在流链的正确部分使用缓冲流?
答案 0 :(得分:0)
无法保证Java的两个副本将生成与对象序列化完全相同的字节 - 只是它们将生成一个语义上等效的对象。
您可以通过在键和值上运行摘要来制作类似的工作,但您需要决定如何散列Object
值。
如果您可以渲染到XML并将其规范化,那么您可以从那里开始。
您可以查看各种Web服务标准的安全性,而不是自己动手。
建议:将哈希映射复制到一个具有顺序的TreeMap中,并尝试使用相同的技巧。
答案 1 :(得分:0)
可能只是从一个JVM发送带有键值对的JSON,而在接收方,您可以反序列化并构造另一个HashMap