Целостность хэш-карты, отправляемой по сети - PullRequest
0 голосов
/ 10 апреля 2011

Мой сервлет шифрует и отправляет HashMap и его MD5-хэш.
Затем клиент получает их и сравнивает MD5 с тем, который он работает из HashMap.

Иногда это работает, но не с другими, например, если 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 различны.(единственное отличие - ключ 'count' вместо 'count')

Программа отправляет аналогичные 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;
    }

дешифрует, используя тот же тип inputStreams, обрабатывает md5 хеш-карты тем же способом, а затем сравнивает, используя:

    if (!Arrays.equals(hash1, hash2)) {
            System.out.println("Result received does not match hash, stopping get operation");
            return;
    }

Я не понимаю, почему это сработало для отправки всех HashMapsЯ пытался, но теперь не работает с этим ключом счета.Я проверил сравнение отдельных пар ключ / значение в HashMap на клиенте и сервлете, и они одинаковы, но при сравнении двух MD5 всего HashMap они не совпадают.

Также,Я не уверен, что я использую буферный поток в правильной части цепочки потоков?

Ответы [ 2 ]

0 голосов
/ 29 апреля 2019

Может быть просто отправить JSON с парами ключ-значение из одной JVM, а на стороне получателя вы можете десериализовать и сконструировать другой HashMap

0 голосов
/ 10 апреля 2011

Нет гарантии, что две копии Java будут производить точно такие же байты, что и сериализация объекта - только то, что они будут создавать семантически эквивалентный объект.

Вы можете сделать что-то вроде этого, запустив дайджесты для ключей и значений, но вам нужно решить, как хешировать значения Object.

Если вы можете выполнить рендеринг в XML и канонизировать его, тогда вы можете перейти оттуда.

Вы можете ознакомиться с различными стандартами веб-сервисов для обеспечения безопасности, вместо того, чтобы использовать свой собственный.

Предложение: скопируйте хеш-карту в TreeMap, у которого есть порядок, и попробуйте тот же трюк с этим.

...