문제

I am currently designing a communication protocol for an embedded system. I've decided that authentication (but not encryption) is important, so I decided to add 4 bytes of truncated HMAC signature to every packet. At the same time, I also want to be able to do data verification to ensure that the data arrives correctly and hasn't been corrupted in transit. So I was thinking of appending a CRC32 to every packet. However, wouldn't the HMAC signature also be good enough for verifying the integrity of the packet?

Is there any point in adding both an HMAC signature and a CRC32? Or is an HMAC enough?

도움이 되었습니까?

해결책

The CRC32 does not give you any guarantees that the HMAC does not also give you. Put another way, the HMAC gives you all the guarantees the CRC32 gives you and more: the CRC32 protects against unintentional alteration due to common transmission problems such as noise and interference, the HMAC also protects against intentional alteration.

The CRC32, however, may be less compute-intensive to verify. So, if your communication channel is very noisy and your receiver device is CPU-constrained, it may make sense to use the additional CRC32 to quickly throw away corrupted packets without having to verify the more expensive HMAC and only do the expensive HMAC verification on packets you know were at least not corrupted during transmission.

This balance may tip, however, if your chosen CPU has built-in acceleration for the cryptographic primitives used in the HMAC.

In the particular case of a noisy channel, it would probably make even more sense to use an Error Correction Code or some other mechanism for Forward Error Correction like a Hamming or Reed-Solomon code instead of only a mere Error Detection Code like CRC32.

다른 팁

If you need secure authentication, use only the untruncated HMAC.

Assuming you don't care about security (which would be the case if you used a 4-byte HMAC), a CRC is actually better for detecting small accidental errors. An n-bit CRC is guaranteed to detect any burst error up to n + 1 bits in length, with the sole exception of a burst error whose polynomial divides the CRC polynomial, in which case the probability of the error going undetected is 1 (i.e. always goes through undetected). For detecting small errors, a CRC is superior. For larger errors which do not divide the CRC polynomial, they are equal, providing a 2-n probability of failure.

Note that this assumes the size of the digest is the same, i.e. CRC64 vs an 8-byte (64-bit) truncated HMAC or CRC32 vs a 4-byte (32-bit) truncated HMAC. Be aware that neither 64 bits nor 32 bits is sufficient to protect against an intentional error that bypasses detection.

The purpose of a Message Authentication Code (MAC), of which the HMAC is an example, is to prove both the authenticity and the integrity of the message.

The integrity protection is often framed as a protection against modification of the message by attackers, but it works equally for detecting accidental modification by bit-flips in the transport of the message. Thus, you don't need an additional CRC check to detect those bit-flips.

CRC in addition to HMAC is pointless if you only verify the checksum at the final recipient, i.e. as a purely end-to-end protocol. However, it can be useful if the checksum is verified at intermediate steps that don't know the secret key. In particular, if the message is relayed through several hops, intermediate hops can delete messages with an invalid CRC.

Once the message has arrived at the final recipient, a CRC allows you to cheaply discard corrupted messages. This aspect is rarely useful in practice. If you're worried about accidental corruption, error correction codes will give you better results than a CRC: resending is a lot more expensive than fixing an error. If you're worried about a denial of service by a flood of invalid message, using a CRC doesn't really gain much: you might save a tiny amount of CPU power because CRC is faster to calculate than HMAC, but an attacker who can flood your CPU can typically flood your radio receiver anyway. One case where this is not true and a CRC can help is if your receiver consists of a fast application CPU combined with a slow secure element, and only the secure element has the HMAC key.

Note that a 32-bit MAC is very short and is only good if you don't mind that it's possible to attack a fleet of devices with a small, but nonzero rate of success. If you deploy a million devices and they can each process one message per second, a somewhat resourceful adversary can inject several fake messages every day. How bad this is depends on how much you can tolerate the occasional fake.

If you think about adding 32 bit CRC and 32 bit truncated HMAC: 32 bit truncated HMAC may be just about forgeable. Calculating HMAC not for the message, but message + CRC, might make it bit harder. What makes it a lot harder to forge would be to throw away the CRC and use a 64 bit truncated HMAC.

Use the right tool for the job.

CRCs provide superior error detection to a same size HMAC function because CRCs detect all burst errors less than the CRC size and all odd numbered of bits errors.

Its also faster to compute CRCs.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 softwareengineering.stackexchange
scroll top