EncryptedMessage CryptoEngine::EncryptWithPublicKeyAndSign(const Message &message, const VerificationEngine &ver_engine) { // check the public key if (ver_engine.public_key().empty()) { std::cout << "The recipient public key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (ver_engine.signing_public_key().empty()) { std::cout << "The recipient signing public key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (private_key_.empty()) { std::cout << "The secret key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (nonce_master_key_.empty()) { std::cout << "The master key for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (context_.empty()) { std::cout << "The context identifier for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (salt_.empty()) { std::cout << "The salt for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } // means the current crypto engine and the recipient crypto engine have the same public keys ! // This is NOT SAFE - stop immediately if(crypto_verify_32 (reinterpret_cast<const unsigned char *>(public_key_.data()), reinterpret_cast<const unsigned char *>(ver_engine.public_key().data())) == 0) { std::cout << "The engine public key and the recipient public key are the same !!! Did you copy the same files to two different peers ? This is NOT SAFE !! STOPPING !" << std::endl; throw g_crypto_engine_encryption_failure; } // derive the nonce std::string nonce = hkdf_.DeriveNonce(nonce_master_key_, salt_); // calculate the hash of the data std::string hash(crypto_hash(message.ToBytesString())); // calculate the signature on the hash std::string signed_hash = crypto_sign(hash, sign_private_key_); // prepend the signature+hash to the message std::string signed_message_string = signed_hash + message.ToBytesString(); // encrypt with the recipient public key std::string cipher_text = crypto_box(signed_message_string, nonce, ver_engine.public_key(), private_key_); return EncryptedMessage(nonce, cipher_text); }
// Decrypt with the same key but from the message bytes EncryptedMessage CryptoEngine::EncryptWithPublicKey(const Message &message, const VerificationEngine &ver_engine) { // check the public key if (ver_engine.public_key().empty()) { std::cout << "The recipient public key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (private_key_.empty()) { std::cout << "The secret key is empty. Cannot encrypt here." << std::endl; throw g_crypto_engine_encryption_failure; } if (nonce_master_key_.empty()) { std::cout << "The master key for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (context_.empty()) { std::cout << "The context identifier for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (salt_.empty()) { std::cout << "The salt for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } // means the current crypto engine and the recipient crypto engine have the same public keys ! // This is NOT SAFE - stop immediately if(crypto_verify_32 (reinterpret_cast<const unsigned char *>(public_key_.data()), reinterpret_cast<const unsigned char *>(ver_engine.public_key().data())) == 0) { std::cout << "The engine public key and the recipient public key are the same !!! Did you copy the same files to two different peers ? This is NOT SAFE !! STOPPING !" << std::endl; throw g_crypto_engine_encryption_failure; } try { // derive the nonce std::string nonce = hkdf_.DeriveNonce(nonce_master_key_, salt_); // Add the additional data (tcp_verion, type, message) to the string std::string full_clear_text(message.ToBytesString()); // encrypt with the recipient public key std::string cipher_text = crypto_box(full_clear_text, nonce, ver_engine.public_key(), private_key_); return EncryptedMessage(nonce, cipher_text); } catch (std::exception& e) { std::cout << "CryptoEngine::Encrypt exception: " << e.what() << std::endl; throw g_crypto_engine_encryption_failure; } }
EncryptedMessage getEncryptedMessage(string xmlString) { vector<char> xml_copy(xmlString.begin(), xmlString.end()); xml_copy.push_back('\0'); rapidxml::xml_document<> doc; rapidxml::xml_node<> * root_node; rapidxml::xml_node<> * mes_node; doc.parse<rapidxml::parse_declaration_node | rapidxml::parse_no_data_nodes>(&xml_copy[0]); root_node = doc.first_node("scramble"); mes_node = root_node->first_node("text"); string encMessage = mes_node->value(); encMessage = base64_decode(encMessage); EncryptedMessage res = EncryptedMessage(encMessage); return res; }
EncryptedMessage CryptoEngine::Encrypt(const Message &message) { if (secret_key_.empty()) { std::cout << "The secret key for symmetric encryption has not been initialized" << std::endl; throw g_crypto_engine_encryption_failure; } if (nonce_master_key_.empty()) { std::cout << "The master key for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (context_.empty()) { std::cout << "The context identifier for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } if (salt_.empty()) { std::cout << "The salt for deriving the nonce is not valid" << std::endl; throw g_crypto_engine_encryption_failure; } try { // generate the Nonce std::string nonce = hkdf_.DeriveNonce(nonce_master_key_, salt_); // Add the additional data (tcp_verion, type, message) to the string std::string full_clear_text(message.ToBytesString()); // encrypt the message std::string cipher_text = crypto_secretbox(full_clear_text, nonce, secret_key_); // return the Message object so that it can be serialized to bytes return EncryptedMessage(nonce, cipher_text); } catch (std::exception& e) { std::cout << "CryptoEngine::Encrypt exception: " << e.what() << std::endl; throw g_crypto_engine_encryption_failure; } }