void cServer::PrepareKeys(void) { // TODO: Save and load key for persistence across sessions // But generating the key takes only a moment, do we even need that? LOGD("Generating protocol encryption keypair..."); time_t CurTime = time(NULL); CryptoPP::RandomPool rng; rng.Put((const byte *)&CurTime, sizeof(CurTime)); m_PrivateKey.GenerateRandomWithKeySize(rng, 1024); CryptoPP::RSA::PublicKey pk(m_PrivateKey); m_PublicKey = pk; }
void Reset() { if (streamEncryption) delete streamEncryption; if (aesEncryption) delete aesEncryption; CryptoPP::RandomPool prng; CryptoPP::SecByteBlock iv(16); CryptoPP::OS_GenerateRandomBlock(false, iv, iv.size()); prng.IncorporateEntropy(iv, iv.size()); memcpy(streamInitialization, iv, iv.size()); aesEncryption = new CryptoPP::AES::Encryption(m_anEncryptionKey, 32); streamEncryption = new CryptoPP::CBC_Mode_ExternalCipher::Encryption( *aesEncryption, streamInitialization); }
void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce) { // Decrypt EncNonce using privkey RSAES<PKCS1v15>::Decryptor rsaDecryptor(cRoot::Get()->GetServer()->GetPrivateKey()); time_t CurTime = time(NULL); CryptoPP::RandomPool rng; rng.Put((const byte *)&CurTime, sizeof(CurTime)); byte DecryptedNonce[MAX_ENC_LEN]; DecodingResult res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncNonce.data(), a_EncNonce.size(), DecryptedNonce); if (!res.isValidCoding || (res.messageLength != 4)) { LOGD("Bad nonce length"); m_Client->Kick("Hacked client"); return; } if (ntohl(*((int *)DecryptedNonce)) != (unsigned)(uintptr_t)this) { LOGD("Bad nonce value"); m_Client->Kick("Hacked client"); return; } // Decrypt the symmetric encryption key using privkey: byte DecryptedKey[MAX_ENC_LEN]; res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncKey.data(), a_EncKey.size(), DecryptedKey); if (!res.isValidCoding || (res.messageLength != 16)) { LOGD("Bad key length"); m_Client->Kick("Hacked client"); return; } { // Send encryption key response: cCSLock Lock(m_CSPacket); WriteByte((char)0xfc); WriteShort(0); WriteShort(0); Flush(); } StartEncryption(DecryptedKey); return; }
void O2Profile:: SetRSAKey(const byte *priv, size_t privlen, const byte *pub, size_t publen) { bool valid = false; if (priv && privlen && pub && publen) { if (privlen == RSA_PRIVKEY_SIZE && publen == RSA_PUBKEY_SIZE) { PrivKey.assign(priv, privlen); PubKey.assign(pub, publen); valid = true; } } if (!valid) { CryptoPP::RandomPool randpool; #ifdef _WIN32 /** windows */ GUID guid; CoCreateGuid(&guid); randpool.Put((byte*)&guid, sizeof(GUID)); #else /** unix */ boost::uuids::random_generator gen; boost::uuids::uuid uuid = gen(); randpool.Put((byte*)&uuid, sizeof(boost::uuids::uuid)); #endif byte tmpPriv[RSA_PRIVKEY_SIZE]; CryptoPP::RSAES_OAEP_SHA_Decryptor priv(randpool, RSA_KEYLENGTH); CryptoPP::ArraySink privArray(tmpPriv, RSA_PRIVKEY_SIZE); priv.DEREncode(privArray); privArray.MessageEnd(); PrivKey.assign(tmpPriv, RSA_PRIVKEY_SIZE); byte tmpPub[RSA_PUBKEY_SIZE]; CryptoPP::RSAES_OAEP_SHA_Encryptor pub(priv); CryptoPP::ArraySink pubArray(tmpPub, RSA_PUBKEY_SIZE); pub.DEREncode(pubArray); pubArray.MessageEnd(); PubKey.assign(tmpPub, RSA_PUBKEY_SIZE); } }
void CEncrypt::CreateOwnerKey() { CryptoPP::RandomPool prng; CryptoPP::SecByteBlock salt(16); CryptoPP::OS_GenerateRandomBlock(false, salt, salt.size()); prng.IncorporateEntropy(salt, salt.size()); memcpy(m_anOwnerKey + 32, salt.data(), salt.size()); CryptoPP::SHA256 hash; hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); hash.Update( m_anOwnerKey + 32, 8); hash.Update( m_anUserKey, 48); CryptoPP::SecByteBlock pHashData(hash.DigestSize()); hash.Final(pHashData); if (MakeFileKey3(impl->m_sOwnerPassword, pHashData.data(), pHashData.size(), m_anUserKey, 48)) { memcpy(m_anOwnerKey, pHashData.data(), pHashData.size()); hash.Update( (unsigned char*) impl->m_sOwnerPassword.c_str(), impl->m_sOwnerPassword.length()); hash.Update( m_anOwnerKey + 40, 8); hash.Update( m_anUserKey, 48); CryptoPP::SecByteBlock pHashKeyData(hash.DigestSize()); hash.Final(pHashKeyData); MakeFileKey3(impl->m_sOwnerPassword, pHashKeyData.data(), pHashKeyData.size(), m_anUserKey, 48); unsigned char empty[16] = {}; CryptoPP::AES::Encryption aesEncryption(pHashKeyData.data(), pHashKeyData.size()); CryptoPP::CBC_Mode_ExternalCipher::Encryption cbcEncryption( aesEncryption, empty); CryptoPP::StreamTransformationFilter stfEncryption(cbcEncryption, new CryptoPP::ArraySink( m_anOwnerEncryptKey, 32), CryptoPP::StreamTransformationFilter::NO_PADDING ); stfEncryption.Put2(impl->m_anEncryptionKey, 32, 1, true); stfEncryption.MessageEnd(); } }
void CEncrypt::CreateEncryptionKey() { CryptoPP::RandomPool prng; CryptoPP::SecByteBlock key(32); CryptoPP::OS_GenerateRandomBlock(false, key, key.size()); prng.IncorporateEntropy(key, key.size()); memcpy(impl->m_anEncryptionKey, key.data(), key.size()); //------------------------------------------------------------------- unsigned long long extended_perms = 0xffffffff00000000LL | m_unPermission; for (int i = 0; i < 8; ++i) { m_anPermEncrypt[i] = static_cast<unsigned char>(extended_perms & 0xff); extended_perms >>= 8; } m_anPermEncrypt[8] = /*m_bEncryptMetadata ? 'T' : */'F'; m_anPermEncrypt[9] = 'a'; m_anPermEncrypt[10] = 'd'; m_anPermEncrypt[11] = 'b'; CryptoPP::SecByteBlock p(4); CryptoPP::OS_GenerateRandomBlock(false, p, p.size()); prng.IncorporateEntropy(p, p.size()); memcpy(m_anPermEncrypt + 12, p.data(), p.size()); unsigned char empty[16] = {}; CryptoPP::AES::Encryption aesEncryption(impl->m_anEncryptionKey, 32); CryptoPP::CipherModeFinalTemplate_ExternalCipher<CryptoPP::ECB_OneWay> ecbEncryption(aesEncryption, empty ); CryptoPP::StreamTransformationFilter stfEncryption(ecbEncryption, new CryptoPP::ArraySink( m_anPermEncrypt, 16), CryptoPP::StreamTransformationFilter::NO_PADDING ); stfEncryption.Put2(m_anPermEncrypt, 16, 1, true); stfEncryption.MessageEnd(); }
void O2Profile:: SetRSAKey(const byte *priv, size_t privlen, const byte *pub, size_t publen) { bool valid = false; if (priv && privlen && pub && publen) { if (privlen == RSA_PRIVKEY_SIZE && publen == RSA_PUBKEY_SIZE) { PrivKey.assign(priv, privlen); PubKey.assign(pub, publen); valid = true; } } if (!valid) { GUID guid; CoCreateGuid(&guid); CryptoPP::RandomPool randpool; randpool.Put((byte*)&guid, sizeof(GUID)); byte tmpPriv[RSA_PRIVKEY_SIZE]; CryptoPP::RSAES_OAEP_SHA_Decryptor priv(randpool, RSA_KEYLENGTH); CryptoPP::ArraySink privArray(tmpPriv, RSA_PRIVKEY_SIZE); priv.DEREncode(privArray); privArray.MessageEnd(); PrivKey.assign(tmpPriv, RSA_PRIVKEY_SIZE); byte tmpPub[RSA_PUBKEY_SIZE]; CryptoPP::RSAES_OAEP_SHA_Encryptor pub(priv); CryptoPP::ArraySink pubArray(tmpPub, RSA_PUBKEY_SIZE); pub.DEREncode(pubArray); pubArray.MessageEnd(); PubKey.assign(tmpPub, RSA_PUBKEY_SIZE); } }