views:

66

answers:

4

I am sending objects to a server in java, however I want to ensure that it has not been tampered with, in addition to the already provided security. I understand how to take do use a message digest, however, should the checksum ideally be placed in the object? and if so wouldnt this change the checksum at the end. How do you go about this? How does it work with TCP headers etc it is starting to confuse me qutie a bit.

Thanks

+1  A: 

Let's say your checksum is 32 bytes long. You calculate your checksum from your data and append the checksum to the end of it. When you receive the data, you know that the checksum occupies the last 32 bytes and the actual data is before the checksum.

Tuomas Pelkonen
A: 

Checksum of the message cannot be part of that message - it would be almost impossible to calculate the checksum.

The checksum must be computed from the message + some secret key. (Without the secret key, attacker could modify the message and easily compute its checksum.) Only problem I see here is that attacker can repeat the message, so if you receive two same messages, you don't know whether the the later one is from the attacker.

Ad TCP headers - why are you bothering about it? Just send the message and the checksum. TCP is just transport protocol; TCP or IP checksums are not for security, they are for detecting transport errors.

Messa
A: 

I believe that TCP & IP calculate their checksums with the checksum fields filled with zeros. Then the receiver calculates the checksums assuming the fields are zeros, and compares with the actual checksum.

Certainly you could do something similar, if you didn't want to take the simple solution of just appending the checksum at the end.

However note that this doesn't provide much protection against tampering, as an attacker can just replace the checksum with a checksum of the changed data. You need public key signatures (with an appropriate trust relationship) to protect against tampering.

Douglas Leeder
A: 

When using tcp/ip, it is reasonable certain that the stream is not corrupted in transit "by accident", so don't bother about that.

If you are worried about security, note that Md5 is not secure, anyone can compute a md5 checksum, you need some sort of secret key or pki-solution for the signing.

Note that "signing" is just authentication, the actual message can still be read by someone else. You need encryption + authentication if you also want the content to be secret.

A simple solution is to send your data over a ssl-socket.

I would recommend turning to bouncycastle for good encryption support.

If the messages are transported in some other way (and might need to be handled by other systems, stored on files, ftp:ed, mq:ed, xml-ed etc etc,) you can serialise the message to a byte[], and sign them using a signer in org.bouncycastle.crypto.signers and calculate and append a signature as a byte[] after the actual message.

In that case, you would need to use a message format so that you can separate and extract both the data and the signature, and then recalulate the signature (using the public key of the sender) and make sure that the received and calculated signatures match.

There are several standards for this, S/MIME, pgp, PKCS#7RFC 3369 , and they are probably better than anything you or me can come up with, so investigate them.

If you are using RMI, you could google "secure rmi" - use a SSL socket factory for instance. If you just want authentication (cleartext+signature), you might even be able to write a authenticating socket factory...

If you have no clue about security, the simplest solution might be to set up a secure tunnel using a VPN or ssh, and send your messages using that.

KarlP
Oh, I forgot, WS-Security is doing just this for webservices/soap, if that's what You are using.
KarlP