From 7886018d6f9135b3806d6c29c60329ad3b7aab14 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 31 May 2017 12:35:27 +0300 Subject: [PATCH] Oox file crypter --- OfficeCryptReader/source/CryptTransform.cpp | 128 +++++++++++++++----- OfficeCryptReader/source/ECMACryptFile.cpp | 12 +- X2tConverter/src/ASCConverters.cpp | 16 ++- 3 files changed, 121 insertions(+), 35 deletions(-) diff --git a/OfficeCryptReader/source/CryptTransform.cpp b/OfficeCryptReader/source/CryptTransform.cpp index 6c7c690134..b3142c2a97 100644 --- a/OfficeCryptReader/source/CryptTransform.cpp +++ b/OfficeCryptReader/source/CryptTransform.cpp @@ -177,34 +177,40 @@ void CorrectHashSize(_buf & hashBuf, int size, unsigned char padding) } _buf Hmac(_buf & buf, CRYPT_METHOD::_hashAlgorithm algorithm, std::string & plain) { + std::string mac; if (algorithm == CRYPT_METHOD::SHA1) { CryptoPP::HMAC hmac(buf.ptr, buf.size); - - //return _buf(mac.BytePtr(), mac.SizeInBytes()); - } - else if (algorithm == CRYPT_METHOD::SHA256) - { - CryptoPP::HMAC hmac(buf.ptr, buf.size); - - //return _buf(mac.BytePtr(), mac.SizeInBytes()); - } - else if (algorithm == CRYPT_METHOD::SHA512) - { - CryptoPP::HMAC hmac(buf.ptr, buf.size); - - std::string mac; CryptoPP::StringSource(plain, true, new CryptoPP::HashFilter(hmac, new CryptoPP::StringSink(mac) ) // HashFilter ); // StringSource - return _buf(mac); + } + else if (algorithm == CRYPT_METHOD::SHA256) + { + CryptoPP::HMAC hmac(buf.ptr, buf.size); + CryptoPP::StringSource(plain, true, + new CryptoPP::HashFilter(hmac, + new CryptoPP::StringSink(mac) + ) // HashFilter + ); // StringSource } - //else - return _buf(); + else if (algorithm == CRYPT_METHOD::SHA512) + { + CryptoPP::HMAC hmac(buf.ptr, buf.size); + + CryptoPP::StringSource(plain, true, + new CryptoPP::HashFilter(hmac, + new CryptoPP::StringSink(mac) + ) // HashFilter + ); // StringSource + + } + + return _buf(mac); } @@ -516,14 +522,14 @@ bool ECMADecryptor::CheckDataIntegrity(unsigned char* data, int size) _buf iv2 = HashAppend(pDataSalt, pBlockHmacValue, cryptData.hashAlgorithm); CorrectHashSize(iv2, cryptData.blockSize, 0x36); - _buf salt; - DecryptCipher(secretKey, iv1, pEncHmacKey, salt, cryptData.cipherAlgorithm); + _buf pSaltHmac; + DecryptCipher(secretKey, iv1, pEncHmacKey, pSaltHmac, cryptData.cipherAlgorithm); _buf expected; DecryptCipher(secretKey, iv2, pEncHmacValue, expected, cryptData.cipherAlgorithm); std::string sData((char*)data, size); - _buf hmac = Hmac(salt, cryptData.hashAlgorithm, sData); + _buf hmac = Hmac(pSaltHmac, cryptData.hashAlgorithm, sData); return (hmac == expected); } @@ -612,6 +618,65 @@ ECMAEncryptor::ECMAEncryptor() void ECMAEncryptor::SetPassword(std::wstring _password) { password = _password; + +//--------- + CryptoPP::RandomPool prng; + + //сгенерить соль + CryptoPP::SecByteBlock seed_salt(cryptData.saltSize); + CryptoPP::OS_GenerateRandomBlock(false, seed_salt, seed_salt.size()); + prng.IncorporateEntropy(seed_salt, seed_salt.size()); + + CryptoPP::SecByteBlock seed_datasalt(cryptData.saltSize); + CryptoPP::OS_GenerateRandomBlock(false, seed_datasalt, seed_datasalt.size()); + prng.IncorporateEntropy(seed_datasalt, seed_datasalt.size()); + + //сгенерить ключ + CryptoPP::SecByteBlock seed_key(cryptData.keySize); + CryptoPP::OS_GenerateRandomBlock(false, seed_key, seed_key.size()); + prng.IncorporateEntropy(seed_key, seed_key.size()); + + //сгенерить проверочный + CryptoPP::SecByteBlock seed_verify(cryptData.saltSize); + CryptoPP::OS_GenerateRandomBlock(false, seed_verify, seed_verify.size()); + prng.IncorporateEntropy(seed_verify, seed_verify.size()); +//--------- + _buf pPassword (password); + _buf empty (NULL, 0, false); + + _buf pBlockKey ((unsigned char*)encrKeyValueBlockKey, 8); + _buf pInputBlockKey ((unsigned char*)encrVerifierHashInputBlockKey, 8); + _buf pValueBlockKey ((unsigned char*)encrVerifierHashValueBlockKey, 8); + + _buf pSalt (seed_salt.m_ptr, seed_salt.m_size); + _buf pDataSalt (seed_datasalt.m_ptr, seed_datasalt.m_size); + _buf pDecryptedKey (seed_key.m_ptr, seed_key.m_size); + +//------------------------------------------------------------------------------------------------ + _buf agileKey = GenerateAgileKey( pSalt, pPassword, pBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm); + + _buf pKeyValue; + EncryptCipher( agileKey, pSalt, pDecryptedKey, pKeyValue, cryptData.cipherAlgorithm); + +//-------------------------------------------- + _buf decryptedVerifierHashInputBytes(seed_verify.m_ptr, seed_verify.m_size); + _buf verifierInputKey = GenerateAgileKey( pSalt, pPassword, pInputBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm ); + + _buf pEncVerInput; + EncryptCipher( verifierInputKey, pSalt, decryptedVerifierHashInputBytes, pEncVerInput, cryptData.cipherAlgorithm); +//-------------------------------------------- + + _buf decryptedVerifierHashBytes = HashAppend(decryptedVerifierHashInputBytes, empty, cryptData.hashAlgorithm); + _buf verifierHashKey = GenerateAgileKey(pSalt, pPassword, pValueBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm); + + _buf pEncVerValue; + EncryptCipher( verifierHashKey, pSalt, decryptedVerifierHashBytes, pEncVerValue, cryptData.cipherAlgorithm); + + cryptData.saltValue = std::string((char*)pSalt.ptr, pSalt.size); + cryptData.dataSaltValue = std::string((char*)pDataSalt.ptr, pDataSalt.size); + cryptData.encryptedKeyValue = std::string((char*)pKeyValue.ptr, pKeyValue.size); + cryptData.encryptedVerifierInput = std::string((char*)pEncVerInput.ptr, pEncVerInput.size); + cryptData.encryptedVerifierValue = std::string((char*)pEncVerValue.ptr, pEncVerValue.size); } void ECMAEncryptor::SetCryptData(_ecmaCryptData & data) @@ -639,6 +704,7 @@ void ECMAEncryptor::UpdateDataIntegrity(unsigned char* data, int size) _buf pDataSalt (cryptData.dataSaltValue); _buf pKeyValue (cryptData.encryptedKeyValue); +//---- _buf agileKey = GenerateAgileKey( pSalt, pPassword, pBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm); _buf secretKey; @@ -651,11 +717,19 @@ void ECMAEncryptor::UpdateDataIntegrity(unsigned char* data, int size) CorrectHashSize(iv2, cryptData.blockSize, 0x36); //---- + CryptoPP::RandomPool prng; + CryptoPP::SecByteBlock seed(cryptData.hashSize); + + CryptoPP::OS_GenerateRandomBlock(false, seed, seed.size()); + prng.IncorporateEntropy(seed, seed.size()); + + _buf pSaltHmac(seed.m_ptr, seed.m_size); + std::string sData((char*)data, size); - _buf hmac = Hmac(pSalt, cryptData.hashAlgorithm, sData); + _buf hmac = Hmac(pSaltHmac, cryptData.hashAlgorithm, sData); _buf pEncHmacKey; - EncryptCipher(secretKey, iv1, pSalt, pEncHmacKey, cryptData.cipherAlgorithm); + EncryptCipher(secretKey, iv1, pSaltHmac, pEncHmacKey, cryptData.cipherAlgorithm); _buf pEncHmacValue; EncryptCipher(secretKey, iv2, hmac, pEncHmacValue, cryptData.cipherAlgorithm); @@ -689,19 +763,17 @@ int ECMAEncryptor::Encrypt(unsigned char* data_inp_ptr, int size, unsigned char* _buf pKeyValue (cryptData.encryptedKeyValue); //------------------------------------------------------------------------------------------------ - //соль нужно сгенерить - _buf agileKey = GenerateAgileKey( pSalt, pPassword, pBlockKey, cryptData.keySize, cryptData.spinCount, cryptData.hashAlgorithm); //тут нужно именно дешифрованый генерить - пока их файла берем _buf pDecryptedKey; DecryptCipher( agileKey, pSalt, pKeyValue, pDecryptedKey, cryptData.cipherAlgorithm); - //зашифровать ключь - _buf pEncryptedKey; - EncryptCipher( agileKey, pSalt, pDecryptedKey, pEncryptedKey, cryptData.cipherAlgorithm); + ////зашифровать ключь + //_buf pEncryptedKey; + //EncryptCipher( agileKey, pSalt, pDecryptedKey, pEncryptedKey, cryptData.cipherAlgorithm); - //??? pEncryptedKey == pKeyValue; + ////??? pEncryptedKey == pKeyValue; //------------------------------------------------------------------------------------------------- _buf iv(cryptData.blockSize); diff --git a/OfficeCryptReader/source/ECMACryptFile.cpp b/OfficeCryptReader/source/ECMACryptFile.cpp index 6aa96d186d..0ea136d265 100644 --- a/OfficeCryptReader/source/ECMACryptFile.cpp +++ b/OfficeCryptReader/source/ECMACryptFile.cpp @@ -42,7 +42,7 @@ #include "../../ASCOfficeDocFile/DocDocxConverter/MemoryStream.h" #include "simple_xml_writer.h" -CRYPT::_ecmaCryptData cryptDataGlobal; +//CRYPT::_ecmaCryptData cryptDataGlobal; for Test using namespace CRYPT; @@ -489,19 +489,19 @@ bool ECMACryptFile::EncryptOfficeFile(std::wstring file_name_inp, std::wstring f _ecmaCryptData cryptData; cryptData.bAgile = true; - cryptData.hashAlgorithm = CRYPT_METHOD::SHA256; + cryptData.hashAlgorithm = CRYPT_METHOD::SHA512; cryptData.keySize = 0x20; cryptData.hashSize = 0x40; cryptData.blockSize = 0x10; cryptData.saltSize = 0x10; ECMAEncryptor cryptor; + + //cryptor.SetCryptData(cryptDataGlobal); //for test !!! + cryptor.SetCryptData(cryptData); //basic settings cryptor.SetPassword(password); - cryptor.SetCryptData(cryptDataGlobal); //for test !!! - //cryptor.SetCryptData(cryptData); //basic settings - NSFile::CFileBinary file; if (!file.OpenFile(file_name_inp)) return false; @@ -737,7 +737,7 @@ bool ECMACryptFile::DecryptOfficeFile(std::wstring file_name_inp, std::wstring f //------------------------------------------------------------------- delete pStorage; - cryptDataGlobal = cryptData; // for encrypt like sample + //cryptDataGlobal = cryptData; // for encrypt like sample & test return result; } diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index d04b2b6c73..2b43ae5fe8 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1514,6 +1514,20 @@ namespace NExtractTools } return AVS_FILEUTILS_ERROR_CONVERT; } + int oox2mscrypt (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, InputParams& params) + { + std::wstring password = params.getPassword(); + + ECMACryptFile cryptReader; + bool bDataIntegrity = false; + + if (cryptReader.EncryptOfficeFile(sFrom, sTo, password) == false) + { + return AVS_FILEUTILS_ERROR_CONVERT; + } + + return S_OK; + } int fromMscrypt (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring & sTemp, InputParams& params) { std::wstring password = params.getPassword(); @@ -1570,7 +1584,7 @@ namespace NExtractTools } return nRes; } - //html + //html int html2doct_dir (const std::wstring &sFrom, const std::wstring &sTo, const std::wstring &sTemp, InputParams& params) { std::vector arFiles;