📄 cypher.cxx
字号:
}void PMessageDigest5::Encode(const void * data, PINDEX len, Code & result){ PMessageDigest5 stomach; stomach.Process(data, len); stomach.Complete(result);}///////////////////////////////////////////////////////////////////////////////// PCypherPCypher::PCypher(PINDEX blkSize, BlockChainMode mode) : blockSize(blkSize), chainMode(mode){}PCypher::PCypher(const void * keyData, PINDEX keyLength, PINDEX blkSize, BlockChainMode mode) : key((const BYTE *)keyData, keyLength), blockSize(blkSize), chainMode(mode){}PString PCypher::Encode(const PString & str){ return Encode((const char *)str, str.GetLength());}PString PCypher::Encode(const PBYTEArray & clear){ return Encode((const BYTE *)clear, clear.GetSize());}PString PCypher::Encode(const void * data, PINDEX length){ PBYTEArray coded; Encode(data, length, coded); return PBase64::Encode(coded);}void PCypher::Encode(const PBYTEArray & clear, PBYTEArray & coded){ Encode((const BYTE *)clear, clear.GetSize(), coded);}void PCypher::Encode(const void * data, PINDEX length, PBYTEArray & coded){ PAssert((blockSize%8) == 0, PUnsupportedFeature); Initialise(TRUE); const BYTE * in = (const BYTE *)data; BYTE * out = coded.GetPointer( blockSize > 1 ? (length/blockSize+1)*blockSize : length); while (length >= blockSize) { EncodeBlock(in, out); in += blockSize; out += blockSize; length -= blockSize; } if (blockSize > 1) { PBYTEArray extra(blockSize); extra[blockSize-1] = (BYTE)length; for (PINDEX i = 0; i < length; i++) extra[i] = *in++; EncodeBlock(extra, out); }}PString PCypher::Decode(const PString & cypher){ PString clear; if (Decode(cypher, clear)) return clear; return PString();}BOOL PCypher::Decode(const PString & cypher, PString & clear){ clear = PString(); PBYTEArray clearText; if (!Decode(cypher, clearText)) return FALSE; if (clearText.IsEmpty()) return TRUE; PINDEX sz = clearText.GetSize(); memcpy(clear.GetPointer(sz+1), (const BYTE *)clearText, sz); return TRUE;}BOOL PCypher::Decode(const PString & cypher, PBYTEArray & clear){ PBYTEArray coded; if (!PBase64::Decode(cypher, coded)) return FALSE; return Decode(coded, clear);}PINDEX PCypher::Decode(const PString & cypher, void * data, PINDEX length){ PBYTEArray coded; PBase64::Decode(cypher, coded); PBYTEArray clear; if (!Decode(coded, clear)) return 0; memcpy(data, clear, PMIN(length, clear.GetSize())); return clear.GetSize();}PINDEX PCypher::Decode(const PBYTEArray & coded, void * data, PINDEX length){ PBYTEArray clear; if (!Decode(coded, clear)) return 0; memcpy(data, coded, PMIN(length, clear.GetSize())); return clear.GetSize();}BOOL PCypher::Decode(const PBYTEArray & coded, PBYTEArray & clear){ PAssert((blockSize%8) == 0, PUnsupportedFeature); if (coded.IsEmpty() || (coded.GetSize()%blockSize) != 0) return FALSE; Initialise(FALSE); const BYTE * in = coded; PINDEX length = coded.GetSize(); BYTE * out = clear.GetPointer(length); for (PINDEX count = 0; count < length; count += blockSize) { DecodeBlock(in, out); in += blockSize; out += blockSize; } if (blockSize != 1) { if (*--out >= blockSize) return FALSE; clear.SetSize(length - blockSize + *out); } return TRUE;}///////////////////////////////////////////////////////////////////////////////// PTEACypherPTEACypher::PTEACypher(BlockChainMode chainMode) : PCypher(8, chainMode){ GenerateKey(*(Key*)key.GetPointer(sizeof(Key)));}PTEACypher::PTEACypher(const Key & keyData, BlockChainMode chainMode) : PCypher(&keyData, sizeof(Key), 8, chainMode){}void PTEACypher::SetKey(const Key & newKey){ memcpy(key.GetPointer(sizeof(Key)), &newKey, sizeof(Key));}void PTEACypher::GetKey(Key & newKey) const{ memcpy(&newKey, key, sizeof(Key));}void PTEACypher::GenerateKey(Key & newKey){ static PRandom rand; //=1 // Explicitly set seed if need known random sequence for (PINDEX i = 0; i < sizeof(Key); i++) newKey.value[i] = (BYTE)rand;}static const DWORD TEADelta = 0x9e3779b9; // Magic number for key schedulevoid PTEACypher::Initialise(BOOL){ k0 = ((const PUInt32l *)(const BYTE *)key)[0]; k1 = ((const PUInt32l *)(const BYTE *)key)[1]; k2 = ((const PUInt32l *)(const BYTE *)key)[2]; k3 = ((const PUInt32l *)(const BYTE *)key)[3];}void PTEACypher::EncodeBlock(const void * in, void * out){ DWORD y = ((PUInt32b*)in)[0]; DWORD z = ((PUInt32b*)in)[1]; DWORD sum = 0; for (PINDEX count = 32; count > 0; count--) { sum += TEADelta; // Magic number for key schedule y += (z<<4)+k0 ^ z+sum ^ (z>>5)+k1; z += (y<<4)+k2 ^ y+sum ^ (y>>5)+k3; /* end cycle */ } ((PUInt32b*)out)[0] = y; ((PUInt32b*)out)[1] = z;}void PTEACypher::DecodeBlock(const void * in, void * out){ DWORD y = ((PUInt32b*)in)[0]; DWORD z = ((PUInt32b*)in)[1]; DWORD sum = TEADelta<<5; for (PINDEX count = 32; count > 0; count--) { z -= (y<<4)+k2 ^ y+sum ^ (y>>5)+k3; y -= (z<<4)+k0 ^ z+sum ^ (z>>5)+k1; sum -= TEADelta; // Magic number for key schedule } ((PUInt32b*)out)[0] = y; ((PUInt32b*)out)[1] = z;}///////////////////////////////////////////////////////////////////////////////// PSecureConfigstatic const char DefaultSecuredOptions[] = "Secured Options";static const char DefaultSecurityKey[] = "Validation";static const char DefaultExpiryDateKey[] = "Expiry Date";static const char DefaultOptionBitsKey[] = "Option Bits";static const char DefaultPendingPrefix[] = "Pending:";PSecureConfig::PSecureConfig(const PTEACypher::Key & prodKey, const PStringArray & secKeys, Source src) : PConfig(DefaultSecuredOptions, src), securedKeys(secKeys), securityKey(DefaultSecurityKey), expiryDateKey(DefaultExpiryDateKey), optionBitsKey(DefaultOptionBitsKey), pendingPrefix(DefaultPendingPrefix){ productKey = prodKey;}PSecureConfig::PSecureConfig(const PTEACypher::Key & prodKey, const char * const * secKeys, PINDEX count, Source src) : PConfig(DefaultSecuredOptions, src), securedKeys(count, secKeys), securityKey(DefaultSecurityKey), expiryDateKey(DefaultExpiryDateKey), optionBitsKey(DefaultOptionBitsKey), pendingPrefix(DefaultPendingPrefix){ productKey = prodKey;}void PSecureConfig::GetProductKey(PTEACypher::Key & prodKey) const{ prodKey = productKey;}PSecureConfig::ValidationState PSecureConfig::GetValidation() const{ PString str; BOOL allEmpty = TRUE; PMessageDigest5 digestor; for (PINDEX i = 0; i < securedKeys.GetSize(); i++) { str = GetString(securedKeys[i]); if (!str.IsEmpty()) { digestor.Process(str.Trim()); allEmpty = FALSE; } } str = GetString(expiryDateKey); if (!str.IsEmpty()) { digestor.Process(str); allEmpty = FALSE; } str = GetString(optionBitsKey); if (!str.IsEmpty()) { digestor.Process(str); allEmpty = FALSE; } PString vkey = GetString(securityKey); if (allEmpty) return (!vkey || GetBoolean(pendingPrefix + securityKey)) ? Pending : Defaults; PMessageDigest5::Code code; digestor.Complete(code); if (vkey.IsEmpty()) return Invalid; BYTE info[sizeof(code)+1+sizeof(DWORD)]; PTEACypher crypt(productKey); if (crypt.Decode(vkey, info, sizeof(info)) != sizeof(info)) return Invalid; if (memcmp(info, &code, sizeof(code)) != 0) return Invalid; PTime now; if (now > GetTime(expiryDateKey)) return Expired; return IsValid;}BOOL PSecureConfig::ValidatePending(){ if (GetValidation() != Pending) return FALSE; PString vkey = GetString(securityKey); if (vkey.IsEmpty()) return TRUE; PMessageDigest5::Code code; BYTE info[sizeof(code)+1+sizeof(DWORD)]; PTEACypher crypt(productKey); if (crypt.Decode(vkey, info, sizeof(info)) != sizeof(info)) return FALSE; PTime expiryDate(0, 0, 0, 1, info[sizeof(code)]&15, (info[sizeof(code)]>>4)+1996, PTime::GMT); PString expiry = expiryDate.AsString("d MMME yyyy", PTime::GMT); // This is for alignment problems on processors that care about such things PUInt32b opt; void * dst = &opt; void * src = &info[sizeof(code)+1]; memcpy(dst, src, sizeof(opt)); PString options(PString::Unsigned, (DWORD)opt); PMessageDigest5 digestor; PINDEX i; for (i = 0; i < securedKeys.GetSize(); i++) digestor.Process(GetString(pendingPrefix + securedKeys[i]).Trim()); digestor.Process(expiry); digestor.Process(options); digestor.Complete(code); if (memcmp(info, &code, sizeof(code)) != 0) return FALSE; SetString(expiryDateKey, expiry); SetString(optionBitsKey, options); for (i = 0; i < securedKeys.GetSize(); i++) { PString str = GetString(pendingPrefix + securedKeys[i]); if (!str.IsEmpty()) SetString(securedKeys[i], str); DeleteKey(pendingPrefix + securedKeys[i]); } DeleteKey(pendingPrefix + securityKey); return TRUE;}void PSecureConfig::ResetPending(){ if (GetBoolean(pendingPrefix + securityKey)) { for (PINDEX i = 0; i < securedKeys.GetSize(); i++) DeleteKey(securedKeys[i]); } else { SetBoolean(pendingPrefix + securityKey, TRUE); for (PINDEX i = 0; i < securedKeys.GetSize(); i++) { PString str = GetString(securedKeys[i]); if (!str.IsEmpty()) SetString(pendingPrefix + securedKeys[i], str); DeleteKey(securedKeys[i]); } } DeleteKey(expiryDateKey); DeleteKey(optionBitsKey);}///////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -