Business Central TempBlob and File Hash

424 Views Asked by At

I'm trying to do something that is harder than expected. I have to send a file (a pdf report, for example), via httprequest with multipart form-data. I managed to do that, only working with the tempblob codeunit (it has to be compatible with cloud environment). The problem is that the provider receiving the file also want the SHA256 hash of the file. Now, the procedure to get the sha256 hash is preatty simple:

+++++++++++++++++CLUD code+++++++++++++++++++++++++++

TempBlob.CreateOutStream(OutStream);

SalesInvoiceHeader2.get('22-XXXXX'); //example No.
RecRef.GetTable(SalesInvoiceHeader2);
RecRef.SetRecFilter();
if REPORT.SaveAs(gRecSelection."Report ID", '', ReportFormat::Pdf, OutStream, RecRef) then begin
TempBlob.CreateInStream(InStream);
end;
HashValue := CU_CryptographyMgmt.GenerateHash(Instream, Algorithm::SHA256);

++++++++++++++++++++++++++++++++++++++++++++

I got the hash value according to the system app. Unfortunately, there is not a reliable hash, and when I send the form to the provider, with the Instream octect-stream and the json with the hash value calculated in that way, I got an error: hash value incorrect. At first I thought it was an error of the webservice I was consuming, but I tried something else.

First of all, I downloded the stream with a filename, and if I check the hash of the file I got, is the same that the provider wants. Then I tried to to the same thing, but not for cloud:

+++++++++++++++++++++On prem Code++++++++++++++++++++++++++++++

SalesInvoiceHeader2.get('22-XXXXX');
SalesInvoiceHeader2.SetRecFilter();
report.SaveAsPdf(gRecSelection."Report ID", 'C:\temp\' + format(SalesInvoiceHeader2."No.") + '.pdf', SalesInvoiceHeader2);
Pdffile.Open('C:\temp\' + format(SalesInvoiceHeader."No.") + '.pdf');
Pdffile.CreateInStream(PdfInstream);
HashValue := CU_CryptographyMgmt.GenerateHash(PdfInstream, Algorithm::SHA256);
Pdffile.Close();

+++++++++++++++++++++++++++++++++++++++++++++++++++

(Pdffile is a File type variable, of course)

in THIS way, the hash is perfectly the same the provider wants. How can I do this to be coud frienly? This must to go in a SaaS environment and at this time I don't see how. Suggestions? Cheers Francesco

I'm expecting some brilliant idea.

1

There are 1 best solutions below

0
On

I wrote some sample code to test this behaviour myself:

pageextension 50100 CustomerListExt extends "Customer Card"
{
    trigger OnOpenPage()
    var
        SalesInvoiceHeader: Record "Sales Invoice Header";
        CryptographyManagement: Codeunit "Cryptography Management";
        TempBlob: Codeunit "Temp Blob";
        RecRef: RecordRef;
        InStream: InStream;
        HashAlgorithmType: Option MD5,SHA1,SHA256,SHA384,SHA512;
        OutStream: OutStream;
        ToFile: Text;
    begin
        TempBlob.CreateOutStream(OutStream);

        SalesInvoiceHeader.FindFirst();
        RecRef.GetTable(SalesInvoiceHeader);
        RecRef.SetRecFilter();
        if REPORT.SaveAs(Report::"Standard Sales - Invoice", '', ReportFormat::Pdf, OutStream, RecRef) then
            TempBlob.CreateInStream(InStream);

        Message(CryptographyManagement.GenerateHash(InStream, HashAlgorithmType::SHA256));
        ToFile := 'SalesInvoice.pdf';
        DownloadFromStream(InStream, 'download', '', 'All files (*.*)|*.*', ToFile);
    end;
}

and compared the checksum with the downloaded file with the help of this site: https://emn178.github.io/online-tools/sha256_checksum.html

and the only difference in the hashes for me is, that the one coming from BC is uppercase and the other one is lowercase.