nsICryptoHash
From MDC
Contents |
[edit] Introduction
nsICryptoHash can be used to compute a cryptographic hash function of some data. You can, for example, calculate the MD5 hash of a file to determine if it contains the data you think it does. The hash algorithms supported are MD2, MD5, SHA-1, SHA-256, SHA-384, and SHA-512. This interface is only available in Firefox 1.5 or newer.
nsICryptoHash is defined in netwerk/base/public/nsICryptoHash.idl. It is scriptable and
unfrozen (hasn't changed since Mozilla 1.8).
[edit] Constants
[edit] Hash Algorithms
These constants represent the hash algorithms supported by this interface. The available values are:
-
MD2 -
MD5 -
SHA1 -
SHA512 -
SHA256 -
SHA384
[edit] Methods
[edit] init
void init(in unsigned long aAlgorithm);
init() initializes the object, indicating which hash algorithm to use by specifying one of the constants defined on the interface. You must call either this method or initWithString() before updating the object with any data.
[edit] Parameters
aAlgorithm
- The hash algorithm to use. Must be one of the constants defined on the interface.
[edit] Exceptions
NS_ERROR_INVALID_ARG
- Indicates that an unsupported algorithm type was passed
[edit] initWithString
void initWithString(in ACString aAlgorithm);
initWithString() initializes the object, indicating which hash algorithm to use by specifying the name of the algorithm as a string, such as "MD5". You must call either this method or init() before updating the object with any data.
[edit] Parameters
aAlgorithm
- The hash algorithm to use
[edit] Exceptions
NS_ERROR_INVALID_ARG
- Indicates that an unsupported algorithm type was passed
[edit] update
void update([const, array, size_is(aLen)] in octet aData, in unsigned long aLen);
update() adds an array of data to be hashed to the object. See Computing the Hash of a String for an example of using this method.
[edit] Parameters
aData
- A buffer to calculate the hash over
aLen
- The length of the buffer
aData
[edit] Exceptions
NS_ERROR_NOT_INITIALIZED
- Indicates that
init()orinitWithString()was not called
[edit] updateFromStream
void updateFromStream(in nsIInputStream aStream, in unsigned long aLen);
updateFromStream() adds data to be hashed from an nsIInputStream. See Computing the Hash of a File for an example of using this method.
[edit] Parameters
aStream
- An input stream to read from
aLen
- How much to read from the given
aStream. PassingPR_UINT32_MAXindicates that all data available will be used to update the hash.
[edit] Exceptions
NS_ERROR_NOT_INITIALIZED
- Indicates that
init()orinitWithString()was not called.
NS_ERROR_NOT_AVAILABLE
- Indicates that the requested amount of data to be calculated into the hash is not available.
[edit] finish
ACString finish(in PRBool aASCII);
finish() completes the hash object and produces the actual hash data.
[edit] Parameters
aASCII
- If true then the returned value is a base-64 encoded string. If false, then the returned value is binary data.
[edit] Return Values
This method returns a hash of the data that was read by this object. This can be either binary data or a base-64 encoded string.
[edit] Exceptions
NS_ERROR_NOT_INITIALIZED
- Indicates that
init()orinitWithString()was not called
init() is called. This call resets the object to its pre-init state.
[edit] Example Code
[edit] Computing the Hash of a File
You can easily compute the hash of a file using nsICryptoHash. You will need to create an instance of nsICryptoHash, open an input stream from a file, and then update the hash with the file. The following example shows how to compute the MD5 hash of a file:
// hardcoded here for convenience
var path = "c:\\windows\\notepad.exe";
var f = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
f.initWithPath(path);
var istream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
// open for reading
istream.init(f, 0x01, 0444, 0);
var ch = Components.classes["@mozilla.org/security/hash;1"]
.createInstance(Components.interfaces.nsICryptoHash);
// we want to use the MD5 algorithm
ch.init(ch.MD5);
// this tells updateFromStream to read the entire file
const PR_UINT32_MAX = 0xffffffff;
ch.updateFromStream(istream, PR_UINT32_MAX);
// pass false here to get binary data back
var hash = ch.finish(false);
// return the two-digit hexadecimal code for a byte
function toHexString(charCode)
{
return ("0" + charCode.toString(16)).slice(-2);
}
// convert the binary hash data to a hex string.
var s = [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
// s now contains your hash in hex
This gives 5eb63bbbe01eeed093cb22bb8f5acdc3 for the hash value. This example, while simple, shows most of the functionality of the interface.
The first thing to note is that when you call the init() method you must specify the hash algorithm to use. All of the available algorithms are specified as constants on the interface.
Also note that when you call the updateFromStream() method, the second parameter is the number of bytes to read. Passing PR_UINT32_MAX here indicates that you want the entire file read.
Finally, note that calling the finish() method produces the hash value. The single parameter to this method is false in this example to return binary data. Passing true returns the hash as a base 64 encoded string. In this example we take the binary data and produce a hexadecimal string of the result, as is commonly output by hashing programs.
[edit] Computing the Hash of a String
Another common operation is computing the hash value of a string. Since hash functions are computed over bytes, you will first need to convert the string to a series of bytes using nsIScriptableUnicodeConverter and a Unicode encoding that you specify.
The example below shows how to convert a string to bytes in the UTF-8 encoding, and then compute the MD5 hash of it. The result is computed as a hex string as in the previous example.
var str = "hello world";
var converter =
Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
// we use UTF-8 here, you can choose other encodings.
converter.charset = "UTF-8";
// result is an out parameter,
// result.value will contain the array length
var result = {};
// data is an array of bytes
var data = converter.convertToByteArray(str, result);
var ch = Components.classes["@mozilla.org/security/hash;1"]
.createInstance(Components.interfaces.nsICryptoHash);
ch.init(ch.MD5);
ch.update(data, data.length);
var hash = ch.finish(false);
// return the two-digit hexadecimal code for a byte
function toHexString(charCode)
{
return ("0" + charCode.toString(16)).slice(-2);
}
// convert the binary hash data to a hex string.
var s = [toHexString(hash.charCodeAt(i)) for (i in hash)].join("");
// s now contains your hash in hex: should be
// 5eb63bbbe01eeed093cb22bb8f5acdc3
In this example, we use the update() method to pass an array of bytes to be hashed. As in the previous example, we convert the binary result to a hex string.