sha256 is the SHA256 Hash of a file. I use then btoa(256) to base64 it.
The result is always
InvalidRequest: Value for x-amz-checksum-sha256 header is invalid.
The AWS Documentation says,
ChecksumSHA256 — (String) The base64-encoded, 256-bit SHA-256 digest of the object. This will only be present if it was uploaded with the object. With multipart uploads, this may not be a checksum value of the object. For more information about how checksums are calculated with multipart uploads, see Checking object integrity in the Amazon S3 User Guide. Checking object integrity - Amazon Simple Storage Service Verify the integrity of objects uploaded and downloaded to Amazon S3.
let sha256conv = btoa(sha256);
const params = {
Bucket: process.env.BUCKET,
Key: path.basename(task.file),
Body: fileData,
ContentType: ContentType || 'application/octet-stream',
CacheControl: "max-age=172800",
ChecksumAlgorithm: 'sha256',
ChecksumSHA256: sha256conv
};
const upload = new AWS.S3.ManagedUpload({
service: s3,
params
});
the sha256 is generated like this:
export async function getFileSha256(fileName, fileSize, onProgress) {
return new Promise((resolve, reject) => {
const hash = crypto.createHash('sha256');
// change to 'binary' if you want a binary hash.
hash.setEncoding('hex');
const bar1 = new cliProgress.SingleBar({}, cliProgress.Presets.shades_classic);
bar1.start(fileSize, 0);
const fd = fs.createReadStream(fileName);
fd.on('data', async chunk => {
let processedBytes = bar1.value + chunk.length;
bar1.update(processedBytes);
await onProgress(processedBytes)
})
fd.on('end', function () {
bar1.stop();
hash.end();
return resolve(hash.read())
});
// read all file and pipe it (write it) to the hash object
fd.pipe(hash);
});
}
(async()=>{
var message = 'helloworld';
var hex = await digest(message);
// hmmm i certainly went round the houses here
// var b64 = b64encode(hex);
var b64 = btoa(hex);
console.log(b64);
})();
async function digest(message) {
var msgUint8 = new TextEncoder().encode(message); // encode as (utf-8) Uint8Array
var hashBuffer = await crypto.subtle.digest('SHA-256',msgUint8); // hash the message
var hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
var hashHex = hashArray.map(b=>b.toString(16).padStart(2,'0')).join(''); // convert bytes to hex string
return hashHex;
}//digest
function b64encode(input){
input = utf8_encode(input);
var output = '';
var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
var i = 0;
while(i<input.length){
var chr1 = input.charCodeAt(i++);
var chr2 = input.charCodeAt(i++);
var chr3 = input.charCodeAt(i++);
var enc1 = chr1>>2;
var enc2 = ((chr1&3)<<4)|(chr2>>4);
var enc3 = ((chr2&15)<<2)|(chr3>>6);
var enc4 = chr3&63;
if(isNaN(chr2)){
enc3 = enc4 = 64;
}else{
if(isNaN(chr3)){
enc4 = 64;
}
}
output = output +
keyStr.charAt(enc1) +
keyStr.charAt(enc2) +
keyStr.charAt(enc3) +
keyStr.charAt(enc4)
;
}//while
return output;
}//encode
function utf8_encode(string){
string = string.replace(/\r\n/g,'\n');
var utftext = "";
for(var n=0;n<string.length;n++){
var c = string.charCodeAt(n);
if(c<128){
utftext += String.fromCharCode(c);
}else{
if((c>127)&&(c<2048)){
utftext += String.fromCharCode((c>>6)|192);
utftext += String.fromCharCode((c&63)|128);
}else{
utftext += String.fromCharCode((c>>12)|224);
utftext += String.fromCharCode(((c>>6)&63)|128);
utftext += String.fromCharCode((c&63)|128);
}
}
}//for
return utftext;
}//utf8_encode
this code produces the same output as
hope this helps