[internal API] New OOXML password hashing and helper functions
Eike Rathke
erack at redhat.com
Mon Mar 5 14:45:19 UTC 2018
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/libreoffice/attachments/20180305/ab789583/attachment.sig>
More information about the LibreOffice
mailing list