6. Public Key Infrastructure

Public Key Infrastructure

The central idea is that, you can use the public key to encrypt the message that you want to send but only the owner with the private key are able to decrypted the message and actually see the message that is intended for them. If the attacker is able to perform a man in the middle attack, the attacker can only see a bunch of encrypted random bits

RSA

Pasted image 20231009093503.png

Public Key

To encrypt a message we raise the message to the public key e and take the modulo n
select large prime p and q, where n=pq, ϕ(n)=(p1)(q1)

c=memod n

where e,n , the public key, is chosen such that 1<e<ϕ(n) and gcd(e,ϕ(n))==1

Decrypting

The private key is d where d is the multiplicative inverse of e mod ϕ(n)

m=cd=med=mϕ(n)+1 mod n

Multiplicative inverse

Using the extended Euclidian algorithm

Using PKI

We use PKI to establish a chain of trust for us to know that the party that we want to communicate with is actually the person that we want to communicate with but not some man in the middle.

Digital signature

You can use your private key to sign a message to form a digital signature and everyone can use this digital signature and decrypt it using the public key to decrypt the digital signature to verify the actual person

Public Key

You can use public key to encrypt a message and only the party of the matching private key is able to decrypt the message

Client-server example

In client-server architecture, the server holds a private key and corresponding public key. The client, on the other hand, holds its own private key and public key. The CA acts as an intermediary that verifies and vouches for the authenticity of these keys.

When a client wants to establish a connection with the server, it first requests the server's public key from the CA. The CA then validates the server's identity and signs the server's public key with its own private key. This signed certificate is sent back to the client.

Upon receiving the certificate, the client can verify its authenticity using the CA's public key, which is usually pre-installed on most devices. If the certificate is valid, it means that the server is who it claims to be.

Next, during an initial handshake process called "SSL/TLS handshake," both parties exchange their respective public keys. The client encrypts a random session key using the server's public key and sends it back to establish a secure communication channel.

The server decrypts this session key using its private key, ensuring that only it can access this shared secret. From this point onwards, all communication between client and server is encrypted using symmetric encryption algorithms using this session key.

Getting a certificate from CA

Step 1: Generate a Private Key

The first step is to generate a public/private key pair for the certificate. This private key will be used to sign the certificate request.
openssl genprsa -aes128 -out keypair.pem 2048

-aes128 meant to encrypt the output file using AES(128 bits)
keypair.pem contains both private and public keys
2048 is the RSA key size

Step 2: Create a Certificate Signing Request (CSR)

The next step is to create a Certificate Signing Request (CSR) using the private key generated in step 1. The CSR contains information about the entity requesting the certificate, such as its name, organization, and public key.
openssl req -new -key keypair.pem -out bank.csr

This command creates a new CSR using the key pair from step 1 and saves it in the file "bank.pem".
-key option specifies the path to the private key used for signing.

Step 3 CA issuing X.509 Cetificate

We will send the csr file to the CA and it will verify that we are the actual owner of the key pair. if the verification is successful, the CA will issue a certificate
openssl ca -in bank.csr -out banke_cert.pem -md sha256 -cert modelCA_cert.pem -keyfile modelCA_key.pem
bank.csr is the csr file that we generated previously
bank_cert.pem is the X.509 certificate
modelCA_cert.pem CA's self-signed certificate
modelCA_key.pem CA's private key

Mitigating MITM

Pasted image 20231009102230.png

Verifying common name

During TLS/SSL handshake browsers conduct two important validations

  1. Checks whether the received certificate is valid or not.
  2. Verifies whether the subject (Common Names) in the certificate is the same as the hostname of the server.
    Not verifying the common name is a common mistake in software

Attacks Surfaces on PKI

Pasted image 20231009102439.png
list out the 4 attack surfaces for PKI and what are its consequences and how they can be potentially be compromised

Attack on CA's Verification process

CA’s job has two parts:

Attack on CA's signing process

Attacks on Algorithms

Digital Certificates depend on two types of algorithms

Attacks on User Confirmation

Types of digital certificates

Domain Validated Certificates (DV)

The CA verifies that the domain record belongs to the applicant
Domain Control Validation is performed on domain name in the certificate request
DCV uses information in the WHOIS database
DCV is conducted via

Organizational Validated Certificates(OV)

Not a very popular type of certificate and the CAs will have to verify the the organizations's record and chekc that the organization is legitamate

Extended Validated Certificates (EV)

The EV certificates require documents that are legally signed from registration authorities
cost higher but trustworthy


Transport Layer Security

TLS is a protocol that provides a secure channel between two communicating application

TLS handshake

Pasted image 20231010122803.png
client hello and server hello is in plain text
the pre-master secret is encrypted using the server public key

Wireshark inspection of TLS

Pasted image 20231010123043.png

Key generation and Exchange

Pasted image 20231010123302.png

Info

client and server random is send in the hello message
everything in grey is encrypted

The SSL session key is a symmetric encryption key that is used to encrypt and decrypt data exchanged between the client and server during an SSL session. The steps involved in SSL session key generation and exchange are as follows:

  1. Client Hello: The SSL handshake process begins with the client sending a "Client Hello" message to the server. This message includes the SSL version supported by the client, a random number called "Client Random," and a list of cipher suites supported by the client.

  2. Server Hello: Upon receiving the "Client Hello" message, the server responds with a "Server Hello" message. This message includes the SSL version selected for the session, another random number called "Server Random," and the chosen cipher suite from the client's list.

  3. Certificate Exchange: The server sends its digital certificate to the client in order to authenticate itself. The certificate contains information about the server's identity, including its public key.

  4. Client Key Exchange: After verifying and validating the server's certificate, the client generates its own random number called "Pre-Master Secret." The client encrypts this Pre-Master Secret using the server's public key obtained from its certificate and sends it to the server.

  5. Server Key Exchange: If necessary (e.g., for certain cipher suites), the server may respond with its own encrypted Pre-Master Secret or additional information required for key exchange.

  6. Master Secret Generation: Both parties independently generate a Master Secret using their respective random numbers (Client Random, Server Random) along with other negotiated parameters during this handshake.

  7. Session Key Generation: Using algorithms like HMAC (Hash-based Message Authentication Code), PRF (Pseudo-Random Function), and the Master Secret, the client and server independently derive the session keys. These session keys are unique to each SSL session and are used for encrypting and decrypting data during the session.

  8. Change Cipher Spec: The client and server notify each other that subsequent messages will be encrypted using the newly generated session keys.

  9. Finished Message: To verify that both parties have successfully derived the same session keys, they exchange "Finished" messages. These messages contain a hash of all previous handshake messages, encrypted using the session keys. If these

TLS Data Transmission

Once the handshake protocol is finished, client and server can start exchanging data
Data is transferred using records
Each record contains a header and payload
Pasted image 20231010123809.png

  1. Fragmentation: The sending party breaks down application data into manageable blocks, known as fragments. Each fragment is processed separately.
  2. Compression (Deprecated in TLS 1.3): In older versions of TLS (prior to 1.3), the fragment could be compressed to reduce the amount of data transmitted. Due to vulnerabilities like CRIME, compression is no longer used in TLS 1.3.
  3. Encryption:
    • A sequence number is associated with each fragment. The sequence number is incremented for every record transmitted.
    • A Message Authentication Code (MAC) is computed for the fragment. The MAC provides integrity and authentication for the data. The computation includes the sequence number, ensuring the order of records.
    • The fragment and the MAC are then encrypted using symmetric encryption with the derived session keys (from the handshake process). The encryption ensures confidentiality.
    • In TLS 1.3, a new construction called "Authenticated Encryption with Associated Data" (AEAD) is used, which combines encryption and authentication into a single step.
  4. Record Protocol: The encrypted fragment (now termed a "record") is then transmitted with a header. The header indicates the content type (e.g., application data, alert) and the version of TLS in use.
  5. Reception and Decryption by Recipient:
    • Upon receiving the record, the recipient decrypts the content using the shared session key.
    • The recipient verifies the MAC to ensure the integrity and authenticity of the data. If the MAC doesn't match, the record is rejected.
    • In the case of older TLS versions that used compression, the decrypted fragment would be decompressed to retrieve the original application data.

SSL Write

Pasted image 20231010123908.png
what are the steps in SSL write, starting from getting the data from the application layer to sending the packet to the transport layer

  1. The SSL protocol is implemented in the application layer of the network stack. When data needs to be sent securely, it is first obtained from the application layer.

  2. The data is then divided into small chunks called records. Each record typically contains a fragment of the original data along with some SSL-specific headers.

  3. The SSL protocol then applies compression (if enabled) to reduce the size of the data, making it more efficient to transmit.

  4. Next, SSL encryption is applied to the compressed data using a symmetric encryption algorithm such as AES or 3DES. This ensures that the data cannot be read by any unauthorized parties.

  5. In addition to encryption, SSL also provides integrity through message authentication codes (MACs). A MAC is generated by applying a cryptographic hash function to the encrypted record and a secret key shared between the client and server.

  6. The encrypted and authenticated record, along with any necessary SSL-specific headers, is then encapsulated into a transport layer packet such as TCP/IP or UDP.

  7. Finally, this packet is passed down to the transport layer for transmission over the network. It will be delivered to its destination where it will go through a similar process in reverse order for decryption and verification at the receiving end.

SSL read

Pasted image 20231010123939.png

  1. The recipient uses its session keys to decrypt and verify integrity of the received data using symmetric encryption algorithms specified in the chosen cipher suite.
  2. If decryption or integrity check fails, an error is raised, and the connection may be terminated.
  3. If decryption and integrity check succeed, the recipient extracts and processes the plaintext application data from the decrypted payload.
  4. The SSL read process continues until all encrypted data has been processed or until an end-of-message indicator is received.

TLS Program

Client program

write a tls client program using c

Sure! Below is an example of a TLS client program written in C using OpenSSL:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#define SERVER_IP "127.0.0.1"
#define SERVER_PORT 443

int main() {
    SSL_CTX *ctx;
    SSL *ssl;
    int sockfd;
    struct sockaddr_in server_addr;

    // Initialize OpenSSL library
    SSL_library_init();
    ERR_load_crypto_strings();
    SSL_load_error_strings();
    
    // Create a new SSL context
    ctx = SSL_CTX_new(TLSv1_2_client_method());
    
    // Load the trust store to verify server's certificate
    if (!SSL_CTX_load_verify_locations(ctx, "/etc/ssl/certs/ca-certificates.crt", NULL)) {
        fprintf(stderr, "Error loading trust store.\n");
        exit(1);
    }
    
    // Create a new socket
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    
    // Configure server address
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    
     if (inet_pton(AF_INET, SERVER_IP, &(server_addr.sin_addr)) <= 0) {
        fprintf(stderr, "Invalid address/ Address not supported\n");
        exit(1);
     }
     
     // Connect to the server
     if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) != 0) {
         fprintf(stderr, "Connection failed.\n");
         exit(1);
     }
     
     // Create a new SSL connection using the socket and context
     ssl = SSL_new(ctx);
     SSL_set_fd(ssl, sockfd);
     
     // Perform the SSL handshake with the server
     if (SSL_connect(ssl) != 1) {
         fprintf(stderr, "SSL Handshake failed.\n");
         exit(1);
     }
     
     // Send data to the server
     char message[] = "Hello, server!";
     SSL_write(ssl, message, strlen(message));
     
     // Receive data from the server
     char buffer[1024];
     int bytes_received = SSL_read(ssl, buffer, sizeof(buffer));

TLS Server program

write a TLS server program in c

Sure, here's an example of a TLS server program written in C:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#include <openssl/ssl.h>
#include <openssl/err.h>

#define SERVER_CERT "server.crt"
#define SERVER_KEY "server.key"

void init_openssl() {
    SSL_load_error_strings();
    OpenSSL_add_ssl_algorithms();
}

void cleanup_openssl() {
    EVP_cleanup();
}

SSL_CTX* create_context() {
    const SSL_METHOD *method;
    SSL_CTX *ctx;

    method = TLS_server_method();
    ctx = SSL_CTX_new(method);
    if (!ctx) {
        perror("Unable to create SSL context");
        exit(EXIT_FAILURE);
    }

    return ctx;
}

void configure_context(SSL_CTX *ctx) {
    SSL_CTX_set_ecdh_auto(ctx, 1);

    if (SSL_CTX_use_certificate_file(ctx, SERVER_CERT, SSL_FILETYPE_PEM) <= 0) {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }

    if (SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY, SSL_FILETYPE_PEM) <= 0 ) {
        ERR_print_errors_fp(stderr);
        exit(EXIT_FAILURE);
    }
}

int main() {
    int sockfd;
    
    init_openssl();
    
    SSL_CTX *ctx = create_context();

    configure_context(ctx);

   
   sockfd = socket(AF_INET, SOCK_STREAM, 0);

   struct sockaddr_in server_addr;
   server_addr.sin_family = AF_INET;
   server_addr.sin_port = htons(8080); // Change this to your desired port
   server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

   bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr));
   listen(sockfd, 5);

   while (1) {
       struct sockaddr_in client_addr;
       int client_len = sizeof(client_addr);
       int client_fd = accept(sockfd, (struct sockaddr*)&client_addr, &client_len);
       
       SSL *ssl = SSL_new(ctx);
       SSL_set_fd(ssl, client_fd);
       
       if (SSL_accept(ssl) <= 0) {
           ERR_print_errors_fp(stderr);
       } else {
           char buff[1024];
           int bytes_read = SSL_read(ssl, buff, sizeof(buff));
           if (bytes_read<= 0) {
			// Connection closed
			close(connection);
			return;
		}

		// Process the received data
		process_data(data);
		
		// Send a response to the client
		send_response(response);
	}

Revision questions

If the ca's private key is stolen by an attacker, what damages can the attacker achieve

What are the major differences between a TLS client and TLS Server