To implement the symmetric key cryptography in ns3 has to generate the secure communication scenarios where the nodes can authenticated the messages using the same secret key. The given below is the detailed procedure on how to implement the symmetric key cryptography in ns3:
Step-by-Step Implementation:
Step 1: Set Up ns3 Environment
- Install ns3: Install the ns3 in the system.
- Familiarize yourself with ns3: Read through the ns3 tutorial to familiarize the basic concepts and structure of ns3 simulations.
Step 2: Define the Network Topology
- Create a Simple Network: Describe a basic network topology using ns3 that contains to generate nodes, setting up channels, and configuring IP addresses. We will use a point-to-point topology for simplicity.
#include “ns3/core-module.h”
#include “ns3/network-module.h”
#include “ns3/internet-module.h”
#include “ns3/point-to-point-module.h”
#include “ns3/applications-module.h”
#include <openssl/aes.h>
#include <openssl/rand.h>
#include <iostream>
#include <iomanip>
using namespace ns3;
// Helper function to generate a random AES key
std::string GenerateAESKey() {
unsigned char key[AES_BLOCK_SIZE];
if (!RAND_bytes(key, AES_BLOCK_SIZE)) {
std::cerr << “Error generating random bytes for AES key” << std::endl;
exit(1);
}
return std::string((char*)key, AES_BLOCK_SIZE);
}
// Helper function to encrypt data using AES
std::string EncryptWithAES(const std::string &data, const std::string &key) {
AES_KEY encryptKey;
AES_set_encrypt_key((const unsigned char*)key.c_str(), 128, &encryptKey);
unsigned char iv[AES_BLOCK_SIZE];
if (!RAND_bytes(iv, AES_BLOCK_SIZE)) {
std::cerr << “Error generating random bytes for IV” << std::endl;
exit(1);
}
std::string ciphertext(data.size() + AES_BLOCK_SIZE, ‘\0’);
AES_cfb128_encrypt((const unsigned char*)data.c_str(), (unsigned char*)&ciphertext[0], data.size(), &encryptKey, iv, nullptr, AES_ENCRYPT);
return std::string((char*)iv, AES_BLOCK_SIZE) + ciphertext;
}
// Helper function to decrypt data using AES
std::string DecryptWithAES(const std::string &data, const std::string &key) {
AES_KEY decryptKey;
AES_set_decrypt_key((const unsigned char*)key.c_str(), 128, &decryptKey);
unsigned char iv[AES_BLOCK_SIZE];
memcpy(iv, data.c_str(), AES_BLOCK_SIZE);
std::string plaintext(data.size() – AES_BLOCK_SIZE, ‘\0’);
AES_cfb128_encrypt((const unsigned char*)data.c_str() + AES_BLOCK_SIZE, (unsigned char*)&plaintext[0], plaintext.size(), &decryptKey, iv, nullptr, AES_DECRYPT);
return plaintext;
}
class SymmetricKeyApp : public Application {
public:
SymmetricKeyApp() {}
virtual ~SymmetricKeyApp() {}
void Setup(Address address, uint16_t port, const std::string &key) {
m_peerAddress = address;
m_peerPort = port;
m_key = key;
}
private:
virtual void StartApplication() {
m_socket = Socket::CreateSocket(GetNode(), TypeId::LookupByName(“ns3::UdpSocketFactory”));
m_socket->Bind();
m_socket->Connect(InetSocketAddress(m_peerAddress, m_peerPort));
// Schedule the first packet transmission
Simulator::Schedule(Seconds(1.0), &SymmetricKeyApp::SendPacket, this);
// Set up the receive callback
m_socket->SetRecvCallback(MakeCallback(&SymmetricKeyApp::ReceivePacket, this));
}
virtual void StopApplication() {
if (m_socket) {
m_socket->Close();
m_socket = 0;
}
}
void SendPacket() {
std::string message = “Hello, this is a secure message!”;
std::string encryptedMessage = EncryptWithAES(message, m_key);
Ptr<Packet> packet = Create<Packet>((uint8_t*)encryptedMessage.c_str(), encryptedMessage.size());
m_socket->Send(packet);
// Schedule the next packet transmission
Simulator::Schedule(Seconds(1.0), &SymmetricKeyApp::SendPacket, this);
}
void ReceivePacket(Ptr<Socket> socket) {
Ptr<Packet> packet = socket->Recv();
uint8_t buffer[1024];
packet->CopyData(buffer, packet->GetSize());
std::string encryptedMessage((char*)buffer, packet->GetSize());
std::string decryptedMessage = DecryptWithAES(encryptedMessage, m_key);
std::cout << “Received message: ” << decryptedMessage << std::endl;
}
Ptr<Socket> m_socket;
Address m_peerAddress;
uint16_t m_peerPort;
std::string m_key;
};
int main(int argc, char *argv[]) {
NodeContainer nodes;
nodes.Create(2); // Example: 2 nodes (1 client, 1 server)
PointToPointHelper pointToPoint;
pointToPoint.SetDeviceAttribute(“DataRate”, StringValue(“1Gbps”));
pointToPoint.SetChannelAttribute(“Delay”, StringValue(“2ms”));
NetDeviceContainer devices;
devices = pointToPoint.Install(nodes);
InternetStackHelper stack;
stack.Install(nodes);
Ipv4AddressHelper address;
address.SetBase(“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer interfaces = address.Assign(devices);
uint16_t port = 9;
// Generate a symmetric key for AES encryption
std::string symmetricKey = GenerateAESKey();
Ptr<SymmetricKeyApp> clientApp = CreateObject<SymmetricKeyApp>();
clientApp->Setup(InetSocketAddress(interfaces.GetAddress(1), port), port, symmetricKey);
nodes.Get(0)->AddApplication(clientApp);
clientApp->SetStartTime(Seconds(2.0));
clientApp->SetStopTime(Seconds(10.0));
Ptr<SymmetricKeyApp> serverApp = CreateObject<SymmetricKeyApp>();
serverApp->Setup(InetSocketAddress(Ipv4Address::GetAny(), port), port, symmetricKey);
nodes.Get(1)->AddApplication(serverApp);
serverApp->SetStartTime(Seconds(1.0));
serverApp->SetStopTime(Seconds(10.0));
Simulator::Run();
Simulator::Destroy();
return 0;
}
Explanation:
- OpenSSL Integration:
- OpenSSL is used for AES encryption and decryption operations. We need to link the OpenSSL library when compiling the ns3 code.
- Helper Functions:
- GenerateAESKey generates a random AES key.
- EncryptWithAES encrypts data using the AES key.
- DecryptWithAES decrypts data using the AES key.
- SymmetricKeyApp Class:
- SymmetricKeyApp class handles the AES key generation, packet encryption, and decryption.
- Setup method initializes the application with the peer address, port, and AES key.
- StartApplication method sets up the socket connection, schedules the first packet transmission, and sets up the receive callback.
- SendPacket method encrypts a message and sends it to the peer node.
- ReceivePacket method decrypts the received message and prints it.
- Main Function:
- Creates a simple point-to-point network with 2 nodes (client and server).
- Generates a symmetric AES key.
- Sets up the SymmetricKeyApp on both client and server nodes with the generated AES key.
- The client sends encrypted messages to the server, and the server decrypts and prints the messages.
Compile and Run:
- Compile the Code: Make certain we have OpenSSL installed in the system. Then, compile the code using the following command:
g++ -std=c++11 -o ns3-skc main.cc -lssl -lcrypto `pkg-config –cflags –libs ns3-dev`
- Run the Simulation: Execute the compiled program:
./ns3-skc
Overall, this script shows how to implement the basic symmetric key cryptography in ns3. We need to expand it then contains the more nodes, complex topologies, and additional cryptographic functionalities as needed. We also provide the additional details regarding the symmetric key cryptography.We have implemented Symmetric Key Cryptography in the ns3tool and provide guidance on how to utilize this tool for your projects on current trending topics. Explore project ideas along with simulation results at ns3simulation.com.