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

📄 raraes.cpp

📁 由7-zip提供的压缩、解压缩程序
💻 CPP
字号:
// Crypto/RarAES/RarAES.h// This code is based on UnRar sources#include "StdAfx.h"#include "RarAES.h"#include "sha1.h"extern void GetCryptoFolderPrefix(TCHAR *path);// {23170F69-40C1-278B-0601-010000000000}DEFINE_GUID(CLSID_CCrypto_AES128_Decoder, 0x23170F69, 0x40C1, 0x278B, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00);namespace NCrypto {namespace NRar29 {CDecoder::CDecoder():  _thereIsSalt(false),  _needCalculate(true),  _rar350Mode(false){  for (int i = 0; i < sizeof(_salt); i++)    _salt[i] = 0;}STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *data, UInt32 size){  bool thereIsSaltPrev = _thereIsSalt;  _thereIsSalt = false;  if (size == 0)    return S_OK;  if (size < 8)    return E_INVALIDARG;  _thereIsSalt = true;  bool same = false;  if (_thereIsSalt == thereIsSaltPrev)  {    same = true;    if (_thereIsSalt)    {      for (int i = 0; i < sizeof(_salt); i++)        if (_salt[i] != data[i])        {          same = false;          break;        }    }  }  for (int i = 0; i < sizeof(_salt); i++)    _salt[i] = data[i];  if (!_needCalculate && !same)    _needCalculate = true;  return S_OK;}static const int kMaxPasswordLength = 127 * 2;STDMETHODIMP CDecoder::CryptoSetPassword(const Byte *data, UInt32 size){  if (size > kMaxPasswordLength)    size = kMaxPasswordLength;  bool same = false;  if (size == buffer.GetCapacity())  {    same = true;    for (UInt32 i = 0; i < size; i++)      if (data[i] != buffer[i])      {        same = false;        break;      }  }  if (!_needCalculate && !same)    _needCalculate = true;  buffer.SetCapacity(size);  memcpy(buffer, data, size);  return S_OK;}STDMETHODIMP CDecoder::Init(){  Calculate();  CreateFilter();  CMyComPtr<ICryptoProperties> cp;  RINOK(_aesFilter.QueryInterface(IID_ICryptoProperties, &cp));  RINOK(cp->SetKey(aesKey, 16));  RINOK(cp->SetInitVector(aesInit, 16));  _aesFilter->Init();  return S_OK;}HRESULT CDecoder::CreateFilter(){  if (_aesFilter)    return S_OK;  TCHAR aesLibPath[MAX_PATH + 64];  GetCryptoFolderPrefix(aesLibPath);  lstrcat(aesLibPath, TEXT("AES.dll"));  return _aesLib.LoadAndCreateFilter(aesLibPath, CLSID_CCrypto_AES128_Decoder, &_aesFilter);}STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size){  return _aesFilter->Filter(data, size);}void CDecoder::Calculate(){  if (_needCalculate)  {    const int kSaltSize = 8;        Byte rawPassword[kMaxPasswordLength + kSaltSize];        memcpy(rawPassword, buffer, buffer.GetCapacity());        int rawLength = buffer.GetCapacity();        if (_thereIsSalt)    {      memcpy(rawPassword + rawLength, _salt, kSaltSize);      rawLength += kSaltSize;    }        CSHA1 sha;    sha.Init();    // seems rar reverts hash for sha.    const int hashRounds = 0x40000;    int i;    for (i = 0; i < hashRounds; i++)    {      sha.Update(rawPassword, rawLength, _rar350Mode);      Byte pswNum[3];      pswNum[0] = (Byte)i;      pswNum[1] = (Byte)(i >> 8);      pswNum[2] = (Byte)(i >> 16);      sha.Update(pswNum, 3, _rar350Mode);      if (i % (hashRounds / 16) == 0)      {        CSHA1 shaTemp = sha;        Byte digest[20];        shaTemp.Final(digest);        aesInit[i / (hashRounds / 16)] = (Byte)digest[4 * 4 + 3];      }    }    /*    // it's test message for sha    const char *message = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq";    sha.Update((const Byte *)message, strlen(message));    */    Byte digest[20];    sha.Final(digest);    for (i = 0; i < 4; i++)      for (int j = 0; j < 4; j++)        aesKey[i * 4 + j] = (digest[i * 4 + 3 - j]);  }  _needCalculate = false;}/*STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream,      ISequentialOutStream *outStream, UInt64 const *inSize,       const UInt64 *outSize,ICompressProgressInfo *progress){  Calculate();  TCHAR aesLibPath[MAX_PATH + 64];  GetCryptoFolderPrefix(aesLibPath);  lstrcat(aesLibPath, TEXT("AES.dll"));  CCoderLibrary aesLib;  CMyComPtr<ICompressCoder2> aesDecoder;  RINOK(aesLib.LoadAndCreateCoder2(aesLibPath, CLSID_CCrypto_AES128_Decoder, &aesDecoder));  CSequentialInStreamImp *ivStreamSpec = new CSequentialInStreamImp;  CMyComPtr<ISequentialInStream> ivStream(ivStreamSpec);  ivStreamSpec->Init(aesInit, 16);  CSequentialInStreamImp *keyStreamSpec = new CSequentialInStreamImp;  CMyComPtr<ISequentialInStream> keyStream(keyStreamSpec);  keyStreamSpec->Init(aesKey, 16);  ISequentialInStream *inStreams[3] = { inStream, ivStream, keyStream };  UInt64 ivSize = 16;  UInt64 keySize = 16;  const UInt64 *inSizes[3] = { inSize, &ivSize, &ivSize, };  return aesDecoder->Code(inStreams, inSizes, 3,       &outStream, &outSize, 1, progress);}*/}}

⌨️ 快捷键说明

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