mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-04-07 13:55:33 +08:00
Oox file crypter
This commit is contained in:
@ -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<CryptoPP::SHA1> hmac(buf.ptr, buf.size);
|
||||
|
||||
//return _buf(mac.BytePtr(), mac.SizeInBytes());
|
||||
}
|
||||
else if (algorithm == CRYPT_METHOD::SHA256)
|
||||
{
|
||||
CryptoPP::HMAC<CryptoPP::SHA256> hmac(buf.ptr, buf.size);
|
||||
|
||||
//return _buf(mac.BytePtr(), mac.SizeInBytes());
|
||||
}
|
||||
else if (algorithm == CRYPT_METHOD::SHA512)
|
||||
{
|
||||
CryptoPP::HMAC<CryptoPP::SHA512> 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<CryptoPP::SHA256> 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<CryptoPP::SHA512> 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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user