YOUSEFUL / DELPHI / COMPONENTS

TAtlasHash

SHA-2, SHA-1 and MD5 hashes and HMAC, in one call or incrementally over bytes, buffers, streams and files.

Class Unit Atlas.Crypto · Inherits TObject · Product Atlas Crypto

Description

The class functions (Compute, OfString, OfFile, Hmac) cover most needs in one call. Create an object when the data arrives in pieces: call Update or UpdateFromStream as often as needed, then Finish once for the digest. The object cannot be reused after Finish; create a new one. An object is one running computation, so give each thread its own; the class functions keep no state and are safe from any thread.

Text is always hashed as UTF-8. With a key, the second constructor computes HMAC, which is how to authenticate a message with a shared secret. Compare received tags with TAtlasBytes.ConstantTimeEquals. The results match FIPS 180 (SHA-2, SHA-1), RFC 1321 (MD5) and RFC 4231 (HMAC) published values in the tests.

Members

MemberKindWhat it does
CreateconstructorStarts a plain hash of the given kind.
CreateconstructorStarts an HMAC with HmacKey.
DestroydestructorReleases the CNG hash and algorithm handles.
UpdatemethodAdds Data to the hash.
UpdatemethodAdds Count bytes starting at Buffer, for data held in a static array or a memory block.
UpdateFromStreammethodAdds everything from the stream's current position to its end, reading 256 KB at a time.
FinishmethodReturns the digest (DigestSize bytes).
DigestSizemethodReturns the digest length in bytes: 32, 48, 64, 20 or 16 for SHA-256, SHA-384, SHA-512, SHA-1 and MD5.
ComputemethodReturns the digest of Data in one call.
OfStringmethodReturns the digest of the UTF-8 encoding of Text.
OfFilemethodReturns the digest of a whole file, read in 256 KB pieces.
HmacmethodReturns the HMAC of Data under Key in one call.

Constructors

Create constructor

constructor Create(Kind: TAtlasHashKind = hkSHA256); overload;

Starts a plain hash of the given kind.

pascal
Hash := TAtlasHash.Create(hkSHA512);

Create constructor

constructor Create(Kind: TAtlasHashKind; const HmacKey: TBytes); overload;

Starts an HMAC with HmacKey. Any key length is accepted, including an empty key.

pascal
Hash := TAtlasHash.Create(hkSHA256, Key);

Destructors

Destroy destructor

destructor Destroy; override;

Releases the CNG hash and algorithm handles. Call Free as usual, whether or not Finish was called.

Methods

Update method

procedure Update(const Data: TBytes); overload;

Adds Data to the hash. An empty array is allowed and changes nothing. Raises EAtlasCryptoError after Finish.

pascal
Hash.Update(TAtlasBytes.OfString(Text));

Update method

procedure Update(const Buffer; Count: Integer); overload;

Adds Count bytes starting at Buffer, for data held in a static array or a memory block. A negative Count raises EAtlasCryptoError.

pascal
Hash.Update(Buffer, SizeOf(Buffer));

UpdateFromStream method

procedure UpdateFromStream(Stream: TStream);

Adds everything from the stream's current position to its end, reading 256 KB at a time. A nil stream raises EAtlasCryptoError. It is a separate name, not an Update overload, so that Update(nil) always means an empty byte array.

pascal
Hash.UpdateFromStream(Stream);

Finish method

function Finish: TBytes;

Returns the digest (DigestSize bytes). Afterwards Update and Finish raise EAtlasCryptoError (The hash has been finished; create a new one).

pascal
Digest := Hash.Finish;

DigestSize method

class function DigestSize(Kind: TAtlasHashKind): Integer; static;

Returns the digest length in bytes: 32, 48, 64, 20 or 16 for SHA-256, SHA-384, SHA-512, SHA-1 and MD5.

pascal
Size := TAtlasHash.DigestSize(hkSHA384);  // 48

Compute method

class function Compute(Kind: TAtlasHashKind; const Data: TBytes): TBytes; static;

Returns the digest of Data in one call. nil is the empty message.

pascal
Digest := TAtlasHash.Compute(hkSHA256, Data);

OfString method

class function OfString(Kind: TAtlasHashKind; const Text: string): TBytes; static;

Returns the digest of the UTF-8 encoding of Text.

pascal
Digest := TAtlasHash.OfString(hkSHA256, 'abc');

OfFile method

class function OfFile(Kind: TAtlasHashKind; const FileName: string): TBytes; static;

Returns the digest of a whole file, read in 256 KB pieces. The file is opened for reading with writes by others denied; a missing or locked file raises the RTL's EFOpenError.

pascal
Digest := TAtlasHash.OfFile(hkSHA256, FileName);

Hmac method

class function Hmac(Kind: TAtlasHashKind; const Key, Data: TBytes): TBytes; static;

Returns the HMAC of Data under Key in one call.

pascal
Tag := TAtlasHash.Hmac(hkSHA256, Key, Data);

Examples

Hash in pieces and authenticate with HMAC

The incremental digest equals the one-call digest, and the HMAC matches RFC 4231 test case 2. Prints TRUE and TRUE.

pascal
uses System.SysUtils, Atlas.Crypto;

procedure HashAndHmac;
var
  Hash: TAtlasHash;
  Pieces: TBytes;
begin
  Hash := TAtlasHash.Create(hkSHA256);
  try
    Hash.Update(TAtlasBytes.OfString('ab'));
    Hash.Update(nil);
    Hash.Update(TAtlasBytes.OfString('c'));
    Pieces := Hash.Finish;
  finally
    Hash.Free;
  end;
  WriteLn(TAtlasBytes.ConstantTimeEquals(Pieces, TAtlasHash.OfString(hkSHA256, 'abc')));
  WriteLn(TAtlasBytes.ToHex(TAtlasHash.Hmac(hkSHA256, TAtlasBytes.OfString('Jefe'),
    TAtlasBytes.OfString('what do ya want for nothing?'))) =
    '5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843');
end;

TAtlasHashKind · TAtlasHashCalculator · TAtlasKdf · TAtlasBytes

Also in Atlas Crypto

TAtlasHashCalculator · TAtlasFileProtector