YOUSEFUL / DELPHI / COMPONENTS
TAtlasHash
SHA-2, SHA-1 and MD5 hashes and HMAC, in one call or incrementally over bytes, buffers, streams and files.
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
| Member | Kind | What it does |
|---|---|---|
Create | constructor | Starts a plain hash of the given kind. |
Create | constructor | Starts an HMAC with HmacKey. |
Destroy | destructor | Releases the CNG hash and algorithm handles. |
Update | method | Adds Data to the hash. |
Update | method | Adds Count bytes starting at Buffer, for data held in a static array or a memory block. |
UpdateFromStream | method | Adds everything from the stream's current position to its end, reading 256 KB at a time. |
Finish | method | Returns the digest (DigestSize bytes). |
DigestSize | method | Returns the digest length in bytes: 32, 48, 64, 20 or 16 for SHA-256, SHA-384, SHA-512, SHA-1 and MD5. |
Compute | method | Returns the digest of Data in one call. |
OfString | method | Returns the digest of the UTF-8 encoding of Text. |
OfFile | method | Returns the digest of a whole file, read in 256 KB pieces. |
Hmac | method | Returns 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.
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.
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.
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.
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.
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).
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.
Size := TAtlasHash.DigestSize(hkSHA384); // 48Compute method
class function Compute(Kind: TAtlasHashKind; const Data: TBytes): TBytes; static;Returns the digest of Data in one call. nil is the empty message.
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.
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.
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.
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.
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;
Related
TAtlasHashKind · TAtlasHashCalculator · TAtlasKdf · TAtlasBytes