Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdlde_md5
[Package bdlde]

Provide a value-semantic type encoding a message in an MD5 digest. More...

Namespaces

namespace  bdlde

Detailed Description

Outline
Purpose:
Provide a value-semantic type encoding a message in an MD5 digest.
Classes:
bdlde::Md5 value-semantic type representing an MD5 digest
See also:
Description:
This component implements a mechanism for computing, updating, and streaming an MD5 digest (a hash comprising 128 bits). One possible application is determining whether or not a message was received without errors, although due to security vulnerabilities, it should no longer be used for this purpose (see the Security section below). This implementation is based on the RFC 1321 specification which can be found at:
  http://www.ietf.org/rfc/rfc1321.txt
Note that an MD5 digest does not aid in error correction.
Security:
Practical collision and chosen-prefix collision attacks are known against MD5. Do not use MD5 to generate digital signatures under any circumstances, and do not use MD5 at all except when it is required for interoperation with legacy systems that use MD5. SHA-2 (available in the bdlde_sha2 component) and SHA-3 are more secure alternatives to MD5.
You might think that your application doesn't require collision resistance. However, (1) you might be mistaken, (2) once you start using MD5, you prevent future versions of your application from being able to rely on collision resistance unless they break backward compatibility, (3) a maintainer of your application might accidentally make a change that implicitly assumes collision resistance, and (4) if you expose MD5 hashes to your users, they might assume that they are secure digital signatures, which will make their applications insecure. In light of the foregoing considerations, and the availability of SHA-2 and SHA-3 as alternatives, there is no justification for using MD5 unless you absolutely have to.
Performance:
The performance of this component is slightly slower than the native openssl implementation of MD5. It is typically within 7% of the speed of the native openssl implementation with an error margin of +/-2%, depending on machine load. A million iterations of the update method will typically take between 0.84s to 0.90s on Sun and 0.68s to 0.69s on IBM. A million iterations of the equivalent function in openssl, MD5_Update, will typically take between 0.80s to 0.85s on Sun and 0.65s to 0.67s on IBM.
Usage:
The following snippets of code illustrate a typical use of the bdlde::Md5 class. Each function would typically execute in separate processes or potentially on separate machines. The senderExample function below demonstrates how a message sender can write a message and its MD5 digest to a bdex output stream. Note that Out may be a typedef of any class that implements the bslx::OutStream protocol:
  void senderExample(Out& output)
      // Write a message and its MD5 digest to the specified 'output'
      // stream.
  {
      // Prepare a message.
      bsl::string message = "This is a test message.";

      // Generate a digest for 'message'.
      bdlde::Md5 digest(message.data(), static_cast<int>(message.length()));

      // Write the message to 'output'.
      output << message;

      // Write the digest to 'output'.
      const int VERSION = 1;
      digest.bdexStreamOut(output, VERSION);
  }
The receiverExample function below illustrates how a message receiver can read a message and its MD5 digest from a bdex input stream, then perform a local MD5 computation to verify that the message was received intact. Note that In may be a typedef of any class that implements the bslx::InStream protocol:
  void receiverExample(In& input)
      // Read a message and its MD5 digest from the specified 'input' stream,
      // and verify the integrity of the message.
  {
      // Read the message from 'input'.
      bsl::string message;
      input >> message;

      // Read the digest from 'input'.
      bdlde::Md5 digest;
      const int VERSION = 1;
      digest.bdexStreamIn(input, VERSION);

      // Locally compute the digest of the received 'message'.
      bdlde::Md5 digestLocal;
      digestLocal.update(message.data(), static_cast<int>(message.length()));

      // Verify that the received and locally-computed digests match.
      assert(digestLocal == digest);
  }
Due to security vulnerabilities in the MD5 algorithm (see the Security section above), the use of MD5 contemplated above is insecure unless the transmission channel is completely trusted, which is often impossible to guarantee in practice. Therefore, MD5 should no longer be used in this way.
Additional Copyright Notice:
The implementation of this component is substantially derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm that was published in the aforementioned RFC 1321.