From 02fa4142a79f0aa32bf8f72081b0b1a2f8244653 Mon Sep 17 00:00:00 2001 From: Kulikova Svetlana Date: Mon, 21 Mar 2022 17:32:45 +0300 Subject: [PATCH] calculate encryption key --- .../graphics/pro/js/wasm/src/drawingfile.cpp | 6 ++-- PdfReader/PdfReader.cpp | 24 --------------- PdfWriter/Src/Document.cpp | 2 ++ PdfWriter/Src/Encrypt.cpp | 29 +++++++++++++++++-- PdfWriter/Src/Encrypt.h | 2 +- PdfWriter/Src/EncryptDictionary.cpp | 9 +++--- PdfWriter/Src/EncryptDictionary.h | 1 + 7 files changed, 37 insertions(+), 36 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 9fe59f4db6..bb750c9865 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -153,9 +153,9 @@ static DWORD GetLength(BYTE* x) int main() { -#define XPS_TEST 1 +#define XPS_TEST 0 #define DJVU_TEST 0 -#define PDF_TEST 0 +#define PDF_TEST 1 #if PDF_TEST BYTE* pPdfData = NULL; DWORD nPdfBytesCount; @@ -174,7 +174,7 @@ int main() Close(test); if (nError == 4) { - std::string sPassword = "Test123"; + std::string sPassword = "123456"; test = Open(pPdfData, nPdfBytesCount, sPassword.c_str()); } else diff --git a/PdfReader/PdfReader.cpp b/PdfReader/PdfReader.cpp index bfc3d4b3a0..571ed8caec 100644 --- a/PdfReader/PdfReader.cpp +++ b/PdfReader/PdfReader.cpp @@ -467,30 +467,6 @@ return 0; XMLConverter::DictToXml(&encrypt, sEncrypt, true); else sEncrypt += L'>'; - - SecurityHandler* secHdlr = SecurityHandler::make(m_pInternal->m_pPDFDocument, &encrypt); - GString* owner_pswd = NSStrings::CreateString(sPassword); - GString* user_pswd = NSStrings::CreateString(sPassword); - if (secHdlr && secHdlr->checkEncryption(owner_pswd, user_pswd)) - { - Guchar* fileKey = secHdlr->getFileKey(); - int keyLength = secHdlr->getFileKeyLength(); - - sEncrypt += L""; - for (int nIndex = 0; nIndex < keyLength; ++nIndex) - { - sEncrypt += L""; - sEncrypt += std::to_wstring((int)fileKey[nIndex]); - sEncrypt += L""; - } - sEncrypt += L""; - } - - RELEASEOBJECT(secHdlr); - delete owner_pswd; - delete user_pswd; encrypt.free(); } else diff --git a/PdfWriter/Src/Document.cpp b/PdfWriter/Src/Document.cpp index f72f4590b9..ccbad41b29 100644 --- a/PdfWriter/Src/Document.cpp +++ b/PdfWriter/Src/Document.cpp @@ -1074,6 +1074,7 @@ namespace PdfWriter { m_pEncryptDict = new CEncryptDict(sEncrypt); m_pEncryptDict->SetPasswords(sPassword, sPassword); + m_pEncryptDict->UpdateKey(); m_bEncrypt = true; } @@ -1145,6 +1146,7 @@ namespace PdfWriter else m_pLastXref->WriteToStream(pStream, pEncrypt); + RELEASEOBJECT(m_pEncryptDict); RELEASEOBJECT(pStream); RELEASEOBJECT(m_pLastXref); m_pXref = NULL; diff --git a/PdfWriter/Src/Encrypt.cpp b/PdfWriter/Src/Encrypt.cpp index 632c8d4d48..15c9770d72 100644 --- a/PdfWriter/Src/Encrypt.cpp +++ b/PdfWriter/Src/Encrypt.cpp @@ -139,11 +139,34 @@ namespace PdfWriter impl->m_sUserPassword = sUserPassword; impl->m_sOwnerPassword = sOwnerPassword; } - bool CEncrypt::SetKey(const BYTE* pSrc, unsigned int unLen) + bool CEncrypt::UpdateKey() { - if (unLen == m_unKeyLen) + CryptoPP::SHA256 hash; + + hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); + hash.Update( m_anUserKey + 32, 8); + + CryptoPP::SecByteBlock pHashData(hash.DigestSize()); + hash.Final(pHashData); + + if (MakeFileKey3(impl->m_sUserPassword, pHashData.data(), pHashData.size()) && 0 == memcmp(pHashData.data(), m_anUserKey, 32)) { - memcpy(impl->m_anEncryptionKey, pSrc, m_unKeyLen); + hash.Update( (unsigned char*) impl->m_sUserPassword.c_str(), impl->m_sUserPassword.length()); + hash.Update( m_anUserKey + 40, 8); + + CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); + hash.Final(pHashKeyData); + + MakeFileKey3(impl->m_sUserPassword, pHashKeyData.data(), pHashKeyData.size()); + unsigned char empty[16] = {}; + + CryptoPP::AES::Decryption aesDecryption(pHashKeyData.data(), pHashKeyData.size()); + CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption( aesDecryption, empty); + + CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::ArraySink( impl->m_anEncryptionKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); + stfDecryptor.Put2(m_anUserEncryptKey, 32, 1, true); + stfDecryptor.MessageEnd(); + return true; } return false; diff --git a/PdfWriter/Src/Encrypt.h b/PdfWriter/Src/Encrypt.h index c787f54ab8..eddb882a33 100644 --- a/PdfWriter/Src/Encrypt.h +++ b/PdfWriter/Src/Encrypt.h @@ -65,7 +65,7 @@ namespace PdfWriter unsigned int CryptBuf(const BYTE* pSrc, BYTE* pDst, unsigned int unLen); void SetPermission(unsigned int unPermission); void SetPasswords(const std::string &sUserPassword, const std::string &sOwnerPassword); - bool SetKey(const BYTE* pSrc, unsigned int unLen); + bool UpdateKey(); SET_FUNC(SetID, m_anEncryptID, ID_LEN); SET_FUNC(SetO, m_anOwnerKey, 48); diff --git a/PdfWriter/Src/EncryptDictionary.cpp b/PdfWriter/Src/EncryptDictionary.cpp index 54df82458d..263ac5ef45 100644 --- a/PdfWriter/Src/EncryptDictionary.cpp +++ b/PdfWriter/Src/EncryptDictionary.cpp @@ -69,11 +69,6 @@ namespace PdfWriter pObj = Get("P"); if (pObj && pObj->GetType() == object_type_NUMBER) m_pEncrypt->SetPermission(((CNumberObject*)pObj)->Get()); - - pObj = Get("FileKey"); - if (pObj && pObj->GetType() == object_type_BINARY) - m_pEncrypt->SetKey(((CBinaryObject*)pObj)->GetValue(), ((CBinaryObject*)pObj)->GetLength()); - Remove("FileKey"); } CEncryptDict::~CEncryptDict() { @@ -201,4 +196,8 @@ namespace PdfWriter CBinaryObject* pEncryptPerm = new CBinaryObject(m_pEncrypt->m_anPermEncrypt, 16); Add("Perms", pEncryptPerm); } + void CEncryptDict::UpdateKey() + { + m_pEncrypt->UpdateKey(); + } } diff --git a/PdfWriter/Src/EncryptDictionary.h b/PdfWriter/Src/EncryptDictionary.h index 128b6d99d4..00c159883d 100644 --- a/PdfWriter/Src/EncryptDictionary.h +++ b/PdfWriter/Src/EncryptDictionary.h @@ -57,6 +57,7 @@ namespace PdfWriter { return m_pEncrypt; } + void UpdateKey(); private: CEncrypt* m_pEncrypt; std::string PadOrTrancatePassword(const std::wstring & wsPassword);