Read the original article:Handling Exceptions When Calculating SHA-256 or MD5 Hash for Empty String
Problem Description
When using cryptoFramework to calculate the hash of an empty string or an empty Uint8Array, an exception is thrown, and it is impossible to obtain the SHA-256 hash value or MD5 result for the empty string.
Problematic code example:
async calcEmptySha256(): Promise<string> {
try {
// 1. Create empty Uint8Array
const emptyData = new Uint8Array();
// 2. Compute SHA-256 hash
const sha256 = cryptoFramework.createMd('SHA256');
await sha256.update({ data: emptyData }); // Throws exception
const hash = await sha256.digest();
// 3. Convert to hex string
return Array.from(hash.data)
.map(b => b.toString(16).padStart(2, '0'))
.join('')
} catch (err) {
let code = (err as BusinessError).code;
let message = (err as BusinessError).message;
console.log('code:' + code + ';message:' + message)
return "";
}
}
Background Knowledge
- update*:* Updates the Md digest with message data.
- digest*:* Finalizes the calculation and produces the hash result.
- The update and digest APIs are a two-step pair; digest is mandatory, update is optional.
- If update is called with empty data, the system throws an “update failed” exception.
Troubleshooting Process
- Debugging with breakpoints confirmed that the exception occurs at sha256.update({ data: emptyData}).
- Exception message: “update failed” when empty data is passed.
Analysis Conclusion
When calling update with empty content, an exception is thrown.
To calculate SHA-256 or MD5 of an empty string:
- For SHA-256, check if the input is empty before calling update . If empty, skip the update step and directly call digest .
- For MD5, the same applies: if the string is empty, skip update and directly call digest .
Solution
Fix for SHA-256:
async calcSha256(inputData: string): Promise<string> {
try {
// 1. Create SHA-256 hash
const sha256 = cryptoFramework.createMd('SHA256');
// 2. Check if input is empty
if (inputData) {
await sha256.update({ data: new Uint8Array(buffer.from(inputData, 'utf-8').buffer) });
}
const hash = await sha256.digest();
// 3. Convert to hex string
return Array.from(hash.data)
.map(b => b.toString(16).padStart(2, '0'))
.join('')
} catch (err) {
let code = (err as BusinessError).code;
let message = (err as BusinessError).message;
console.log('code:' + code + ';message:' + message)
return '';
}
}
Fix for MD5 (skip update for empty string):
async function doMd() {
let mdAlgName = 'MD5'; // Algorithm name
let message = ''; // Data to digest
let md = cryptoFramework.createMd(mdAlgName);
try {
await md.update({ data: new Uint8Array(buffer.from(message, 'utf-8').buffer) });
} catch (error) {
console.log(error) // Will fail if message is empty
}
let mdResult = await md.digest();
console.info('Md result:' + mdResult.data);
let mdLen = md.getMdLength();
console.info("Md len: " + mdLen);
let res = Array.from(mdResult.data).map(byte => byte.toString(16)).join('')
console.info("res: " + res);
}
Verification Result
After adding input checks, no exception is thrown.
SHA-256 and MD5 correctly return hash values for both non-empty and empty strings.
Empty string input now produces a valid digest instead of an exception

Top comments (0)