-
-
Notifications
You must be signed in to change notification settings - Fork 394
Home
Welcome to the jsSHA wiki! If there is an eventual need, this page will be split up into separate sub-pages but, for now, it will be one page with sections.
Starting in v3.1, the jsSHA API changed with the deprecation of setHMACKey
and getHMAC
in favor of specifying the HMAC key at object instantiation and getHash
, respectively. I am usually loathe changing the jsSHA API and doubly so with a minor version bump. The reasoning behind this change can be read below.
Usage of jsSHA typically involves three calls:
// See below for constructor arguments
const hash = new jsSHA(...);
hash.update("Stuff to hash")
// The first argument can be one of "HEX" | "B64" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY".
// This can also be called multiple times
hash.getHash("HEX")
// For variable-length hashes (SHAKE, CSHAKE, and KMAC), you must specify the output length, in bits:
// hash.getHash("HEX", { outputLen: 256 })
The constructor is most easily understood if you group jsSHA into four families that depend on the usage: normal hashing, HMAC, CSHAKE, and KMAC. These all use a bag-of-options argument, option
, that uses a "basic" input type for many of its key/value pairs.
The new API options are built on a new "basic" type, called GenericInputType
, that encompasses an input value:
type GenericInputType =
| {
value: string;
format: "TEXT";
encoding?: "UTF8" | "UTF16LE" | "UTF16BE";
}
| {
value: string;
format: "B64" | "HEX" | "BYTES";
}
| {
value: ArrayBuffer;
format: "ARRAYBUFFER";
}
| {
value: Uint8Array;
format: "UINT8ARRAY";
};
In human speak:
- For "TEXT" string-type inputs, you must specify
value
which is a string, you must specify aformat
with the literal string "TEXT", and you may specifyencoding
which must be one of the literal strings "UTF8", "UTF16LE", or "UTF16BE". Ifencoding
is omitted, it defaults to "UTF8". - For "B64", "HEX", and "BYTES" string-type inputs, you must specify both
value
which is a string and aformat
which must be one of the literal strings "B64", "HEX", or "BYTES". - For ArrayBuffer inputs, you must specify both
value
which is anArrayBuffer
and aformat
which must be the literal string "ARRAYBUFFER". - For Uint8Array inputs, you must specify both
value
which is anUint8Array
and aformat
which must be the literal string "UINT8ARRAY".
// For future "TEXT" inputs:
const hash = new jsSHA(
variant: "SHA-1" | "SHA-224" | "SHA-256" | "SHA-384" | "SHA-512" | "SHA3-224" | "SHA3-256" | "SHA3-384" | "SHA3-512" | "SHAKE128" | "SHAKE256",
inputFormat: "TEXT",
options: { encoding?: "UTF8" | "UTF16LE" | "UTF16BE" }
);
// For future non-"TEXT" inputs:
const hash = new jsSHA(
variant: "SHA-1" | "SHA-224" | "SHA-256" | "SHA-384" | "SHA-512" | "SHA3-224" | "SHA3-256" | "SHA3-384" | "SHA3-512" | "SHAKE128" | "SHAKE256",
inputFormat: "B64" | "HEX" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY");
);
The only difference between the two is the omission of the options
argument which, as it only contains key/values relevant for parsing "TEXT" inputs, isn't needed for non-"TEXT" inputs. variant
specifies the desired algorithm to use and inputFormat
influences how future .update()
calls are interpreted.
The HMAC constructor is a superset of the "normal" constructor but with the addition of an extra options
key/value called hmacKey
whose value is of type GenericInputType
as described earlier. In code:
// For future "TEXT" inputs:
const hash = new jsSHA(
variant: "SHA-1" | "SHA-224" | "SHA-256" | "SHA-384" | "SHA-512" | "SHA3-224" | "SHA3-256" | "SHA3-384" | "SHA3-512",
inputFormat: "TEXT",
options: {
encoding?: "UTF8" | "UTF16LE" | "UTF16BE";
hmacKey: GenericInputType
}
);
// For future non-"TEXT" inputs:
const hash = new jsSHA(
variant: "SHA-1" | "SHA-224" | "SHA-256" | "SHA-384" | "SHA-512" | "SHA3-224" | "SHA3-256" | "SHA3-384" | "SHA3-512",
inputFormat: "B64" | "HEX" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY",
options: {
hmacKey: GenericInputType
}
);
Again, the only difference between the two forms is the omission of the encoding
key in the options
argument. Also note that SHAKE128 and SHAKE256 do not support HMAC.
The CSHAKE constructor is similarly a superset of the "normal" constructor but with the addition of an extra options
keys/values called customization
and funcName
whose value are of type GenericInputType
as described earlier. These represent the "customization" and "function-name" parameters described in the NIST CSHAKE specification. In code:
// For future "TEXT" inputs:
const hash = new jsSHA(
variant: "CSHAKE128" | "CSHAKE256",
inputFormat: "TEXT",
options: {
encoding?: "UTF8" | "UTF16LE" | "UTF16BE";
customization?: GenericInputType;
funcName?: GenericInputType;
}
);
// For future non-"TEXT" inputs:
const hash = new jsSHA(
variant: "CSHAKE128" | "CSHAKE256",
inputFormat: "B64" | "HEX" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY",
options: {
customization?: GenericInputType;
funcName?: GenericInputType;
}
);
Again, the only difference between the two forms is the omission of the encoding
key in the options
argument. The customization
and funcName
keys are both optional, as specified by NIST.
The KMAC constructor is similarly a superset of the "normal" constructor but with the addition of an extra options
keys/values called customization
and kmacKey
whose value are of type GenericInputType
as described earlier. These represent the "customization" and KMAC key parameters described in the NIST KMAC specification. In code:
// For future "TEXT" inputs:
const hash = new jsSHA(
variant: "KMAC128" | "KMAC256",
inputFormat: "TEXT",
options: {
encoding?: "UTF8" | "UTF16LE" | "UTF16BE";
customization?: GenericInputType;
kmacKey: GenericInputType;
}
);
// For future non-"TEXT" inputs:
const hash = new jsSHA(
variant: "KMAC128" | "KMAC256",
inputFormat: "B64" | "HEX" | "BYTES" | "ARRAYBUFFER" | "UINT8ARRAY",
options: {
customization?: GenericInputType;
kmacKey: GenericInputType;
}
);
Again, the only difference between the two forms is the omission of the encoding
key in the options
argument. The customization
is optional, as specified by NIST, whereas kmacKey
is required.
Depending on the inputFormat
value specified at instantiation, .update()
expects its sole argument to be either a string
, ArrayBuffer
, or Uint8Array
. .update()
may be called multiple times.
.getHash()
expects the first argument to be one of the string literals "B64", "HEX", "BYTES", "ARRAYBUFFER", "UINT8ARRAY which affects the output type:
- "B64", "HEX" and "BYTES" cause a
string
to be returned. - "ARRAYBUFFER" causes an
ArrayBuffer
to be returned. - "UINT8ARRAY" causes an
Uint8Array
to be returned.
For variable-length hashes (SHAKE, CSHAKE, and KMAC), options
must be in the form of {outputLen: number}
where outputLen
is the desired output length, in bits, and must be a multiple of 8.
For "B64" output type, options
may in the form of {b64Pad: string}
where b64Pad
is the extra padding associated with Base-64 encoding, defaulting to "=".
For "HEX" output type, options
may in the form of {outputUpper: boolean}
where outputUpper
causes the output to be capitalized if true
, defaults to false
.