⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 7zaes.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
字号:
// 7z_AES.cpp#include "StdAfx.h"#include "Windows/Defs.h"#include "Windows/Synchronization.h"#ifndef _WIN32#include "Windows/FileDir.h"#endif#include "../../Common/StreamObjects.h"#include "../../Common/StreamUtils.h"#include "7zAES.h"// #include "../../Hash/Common/CryptoHashInterface.h"#ifdef CRYPTO_AES#include "../AES/MyAES.h"#endif#include "SHA256.h"using namespace NWindows;#ifndef CRYPTO_AESextern HINSTANCE g_hInstance;#endifnamespace NCrypto {namespace NSevenZ {bool CKeyInfo::IsEqualTo(const CKeyInfo &a) const{  if (SaltSize != a.SaltSize || NumCyclesPower != a.NumCyclesPower)    return false;  for (UInt32 i = 0; i < SaltSize; i++)    if (Salt[i] != a.Salt[i])      return false;  return (Password == a.Password);}void CKeyInfo::CalculateDigest(){  if (NumCyclesPower == 0x3F)  {    UInt32 pos;    for (pos = 0; pos < SaltSize; pos++)      Key[pos] = Salt[pos];    for (UInt32 i = 0; i < Password.GetCapacity() && pos < kKeySize; i++)      Key[pos++] = Password[i];    for (; pos < kKeySize; pos++)      Key[pos] = 0;  }  else  {    NCrypto::NSHA256::SHA256 sha;    const UInt64 numRounds = UInt64(1) << (NumCyclesPower);    Byte temp[8] = { 0,0,0,0,0,0,0,0 };    for (UInt64 round = 0; round < numRounds; round++)    {      sha.Update(Salt, SaltSize);      sha.Update(Password, Password.GetCapacity());      sha.Update(temp, 8);      for (int i = 0; i < 8; i++)        if (++(temp[i]) != 0)          break;    }    sha.Final(Key);  }}bool CKeyInfoCache::Find(CKeyInfo &key){  for (int i = 0; i < Keys.Size(); i++)  {    const CKeyInfo &cached = Keys[i];    if (key.IsEqualTo(cached))    {      for (int j = 0; j < kKeySize; j++)        key.Key[j] = cached.Key[j];      if (i != 0)      {        Keys.Insert(0, cached);        Keys.Delete(i+1);      }      return true;    }  }  return false;}void CKeyInfoCache::Add(CKeyInfo &key){  if (Find(key))    return;  if (Keys.Size() >= Size)    Keys.DeleteBack();  Keys.Insert(0, key);}static CKeyInfoCache g_GlobalKeyCache(32);static NSynchronization::CCriticalSection g_GlobalKeyCacheCriticalSection;CBase::CBase():  _cachedKeys(16){  for (int i = 0; i < sizeof(_iv); i++)    _iv[i] = 0;}void CBase::CalculateDigest(){  NSynchronization::CCriticalSectionLock lock(g_GlobalKeyCacheCriticalSection);  if (_cachedKeys.Find(_key))    g_GlobalKeyCache.Add(_key);  else  {    if (!g_GlobalKeyCache.Find(_key))    {      _key.CalculateDigest();      g_GlobalKeyCache.Add(_key);    }    _cachedKeys.Add(_key);  }}/*static void GetRandomData(Byte *data){  // probably we don't need truly random.  // it's enough to prevent dictionary attack;  // but it gives some info about time when compressing   // was made.   UInt64 tempValue;  SYSTEMTIME systemTime;  FILETIME fileTime;  ::GetSystemTime(&systemTime);  ::SystemTimeToFileTime(&systemTime, &fileTime);  tempValue = *(const UInt64 *)&fileTime;  LARGE_INTEGER counter;  ::QueryPerformanceCounter(&counter);  tempValue += *(const UInt64 *)&counter;  tempValue += (UInt64)(GetTickCount()) << 32;  *(UInt64 *)data = tempValue;}*/STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream){   _key.Init();  for (UInt32 i = 0; i < sizeof(_iv); i++)    _iv[i] = 0;  _key.SaltSize = 0;    // _key.SaltSize = 8;  // GetRandomData(_key.Salt);  int ivSize = 0;    // _key.NumCyclesPower = 0x3F;  _key.NumCyclesPower = 18;  Byte firstByte = _key.NumCyclesPower |     (((_key.SaltSize == 0) ? 0 : 1) << 7) |    (((ivSize == 0) ? 0 : 1) << 6);  RINOK(outStream->Write(&firstByte, 1, NULL));  if (_key.SaltSize == 0 && ivSize == 0)    return S_OK;  Byte saltSizeSpec = (_key.SaltSize == 0) ? 0 : (_key.SaltSize - 1);  Byte ivSizeSpec = (ivSize == 0) ? 0 : (ivSize - 1);  Byte secondByte = ((saltSizeSpec) << 4) | ivSizeSpec;  RINOK(outStream->Write(&secondByte, 1, NULL));  if (_key.SaltSize > 0)  {    RINOK(WriteStream(outStream, _key.Salt, _key.SaltSize, NULL));  }  if (ivSize > 0)  {    RINOK(WriteStream(outStream, _iv, ivSize, NULL));  }  return S_OK;}STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size){  _key.Init();  UInt32 i;  for (i = 0; i < sizeof(_iv); i++)    _iv[i] = 0;  if (size == 0)    return S_OK;  UInt32 pos = 0;  Byte firstByte = data[pos++];  _key.NumCyclesPower = firstByte & 0x3F;  if ((firstByte & 0xC0) == 0)    return S_OK;  _key.SaltSize = (firstByte >> 7) & 1;  UInt32 ivSize = (firstByte >> 6) & 1;  if (pos >= size)    return E_INVALIDARG;  Byte secondByte = data[pos++];    _key.SaltSize += (secondByte >> 4);  ivSize += (secondByte & 0x0F);    if (pos + _key.SaltSize + ivSize > size)    return E_INVALIDARG;  for (i = 0; i < _key.SaltSize; i++)    _key.Salt[i] = data[pos++];  for (i = 0; i < ivSize; i++)    _iv[i] = data[pos++];  return S_OK;}STDMETHODIMP CBaseCoder::CryptoSetPassword(const Byte *data, UInt32 size){  _key.Password.SetCapacity(size);  memcpy(_key.Password, data, size);  return S_OK;}/*static Byte *WideToRaw(const wchar_t *src, Byte *dest, int destSize=0x10000000){  for (int i = 0; i < destSize; i++, src++)  {    dest[i * 2] = (Byte)*src;    dest[i * 2 + 1]= (Byte)(*src >> 8);    if (*src == 0)      break;  }  return(dest);}*/#ifndef CRYPTO_AESbool GetAESLibPath(TCHAR *path){  TCHAR fullPath[MAX_PATH + 1];  if (::GetModuleFileName(g_hInstance, fullPath, MAX_PATH) == 0)    return false;  LPTSTR fileNamePointer;  DWORD needLength = ::GetFullPathName(fullPath, MAX_PATH + 1,       path, &fileNamePointer);  if (needLength == 0 || needLength >= MAX_PATH)    return false;#ifdef ENV_UNIX // FIXED  lstrcpy(fileNamePointer, TEXT("../Codecs/AES.so"));#else  lstrcpy(fileNamePointer, TEXT("AES.dll"));#endif  return true;}#endifSTDMETHODIMP CBaseCoder::Init(){  CalculateDigest();  if (_aesFilter == 0)  {    RINOK(CreateFilter());  }  CMyComPtr<ICryptoProperties> cp;  RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));  RINOK(cp->SetKey(_key.Key, sizeof(_key.Key)));  RINOK(cp->SetInitVector(_iv, sizeof(_iv)));  return S_OK;}STDMETHODIMP_(UInt32) CBaseCoder::Filter(Byte *data, UInt32 size){  return _aesFilter->Filter(data, size);}#ifndef CRYPTO_AESHRESULT CBaseCoder::CreateFilterFromDLL(REFCLSID clsID){  if (!_aesLibrary)  {    TCHAR filePath[MAX_PATH + 2];    if (!GetAESLibPath(filePath))      return ::GetLastError();    return _aesLibrary.LoadAndCreateFilter(filePath, clsID, &_aesFilter);  }  return S_OK;}#endifHRESULT CEncoder::CreateFilter(){  #ifdef CRYPTO_AES  _aesFilter = new CAES256_CBC_Encoder;  return S_OK;  #else  return CreateFilterFromDLL(CLSID_CCrypto_AES256_Encoder);  #endif}HRESULT CDecoder::CreateFilter(){  #ifdef CRYPTO_AES  _aesFilter = new CAES256_CBC_Decoder;  return S_OK;  #else  return CreateFilterFromDLL(CLSID_CCrypto_AES256_Decoder);  #endif}}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -