Date: prev next · Thread: first prev next last
2018 Archives by date, by thread · List index


Hi,

With a series of commits for
https://bugs.documentfoundation.org/show_bug.cgi?id=104250
and some follow-ups we now have functions to generate proper password
hash values as specified in OOXML, see also
https://msdn.microsoft.com/en-us/library/dd925430 (Standard Encrytpion)
https://msdn.microsoft.com/en-us/library/dd924776 (Agile Encryption)
https://msdn.microsoft.com/en-us/library/dd920692 (ISO Write Protection Method)

The actual "raw" implementation is in comphelper::Hash with

    static std::vector<unsigned char> calculateHash(
            const unsigned char* pInput, size_t nLength,
            const unsigned char* pSalt, size_t nSaltLen,
            sal_uInt32 nSpinCount,
            IterCount eIterCount,
            HashType eType);

and a convenience function that takes an UTF-16 encoded password string
and a vector with salt value

    static std::vector<unsigned char> calculateHash(
            const rtl::OUString& rPassword,
            const std::vector<unsigned char>& rSaltValue,
            sal_uInt32 nSpinCount,
            IterCount eIterCount,
            HashType eType);

See include/comphelper/hash.hxx and descriptions there.

Along with that there are some convenience and helper functions at
comphelper::DocPasswordHelper, see
include/comphelper/docpasswordhelper.hxx
and descriptions there.

    static css::uno::Sequence<sal_Int8> GetOoxHashAsSequence(
            const rtl::OUString& rPassword,
            const rtl::OUString& rSaltValue,
            sal_uInt32 nSpinCount,
            comphelper::Hash::IterCount eIterCount,
            const rtl::OUString& rAlgorithmName);

    static rtl::OUString GetOoxHashAsBase64(
            const rtl::OUString& rPassword,
            const rtl::OUString& rSaltValue,
            sal_uInt32 nSpinCount,
            comphelper::Hash::IterCount eIterCount,
            const rtl::OUString& rAlgorithmName);

    static std::vector<unsigned char> GetOoxHashAsVector(
            const rtl::OUString& rPassword,
            const std::vector<unsigned char>& rSaltValue,
            sal_uInt32 nSpinCount,
            comphelper::Hash::IterCount eIterCount,
            const rtl::OUString& rAlgorithmName);

Specifically GetOoxHashAsBase64() can be used to pass the strings
obtained from the OOXML file as they are and compare the result against
the document's hashValue string.

oox/source/crypto/AgileEngine.cxx
oox::core::AgileEngine::calculateHashFinal() now uses
comphelper::DocPasswordHelper::GetOoxHashAsVector()

Newer OOXML documents written by MS use "SHA512" (for encryption) or
"SHA-512" (for sheetProtection and fileSharing elelements and maybe
others) algorithm names. The helper functions accept both.

Note that to calculate hashes for new passwords a new salt value MUST be
generated and never existing salts reused, otherwise the whole purpose
of salts is defeated.. for this
comphelper::DocPasswordHelper::GenerateRandomByteSequence() can be used,
a length of 16 currently seems to be a common value.

Happy Hashing

  Eike

-- 
LibreOffice Calc developer. Number formatter stricken i18n transpositionizer.
GPG key 0x6A6CD5B765632D3A - 2265 D7F3 A7B0 95CC 3918  630B 6A6C D5B7 6563 2D3A
Care about Free Software, support the FSFE https://fsfe.org/support/?erack

Attachment: signature.asc
Description: PGP signature


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.