Logo  

CS473 - Computer Networks

Encrypting data-transfers:

To encrypt the transfer of data (and authorization information) we might use a stream cipher or block cipher. Either rely on both ends using a shared key (a number) that that is the seed or initialization value of the cipher. For purposes of this course we will discuss stream ciphers as the mechanism of block ciphers is a bit more involved, and this is not a proper cryptography course.

Stream ciphers

The key that is shared between the two who wish to communicate in secret is used as the seed of a pseudo-random number generator (PRNG). For any given seed a PRNG will always generate the same sequence of "random" looking values, and so long as both the client and server use the same seed, with the same PRNG, they will each get the same sequence of values from it. The data to be sent/received is then transformed using the XOR function with the PRNG.

  • Given:
    k = The shared key.
    m = a message to be sent / received.
    e = The encrypted version of m.
    PRNGk = The PRNG seeded with k.
    ^ = the XOR (Exclusive OR) function

    Then:
    e = m ^ PRNGk
    m = e ^ PRNGk

  • This works because the XOR function is a "reversible" function.

Normally the shared key (k) would be determined using a key-exchange protocol such as Diffie-Helman or the RSA (Rivest–Shamir–Adleman) crypto-system are used to exchange a key such that no outside observer can view the exchanged key. The protocol for RSA is thus:

  • Bob wishes to send information to Alice:
  1. Alice creates a public and private key and publishes the public key in such a way that Bob has it (Alice sends it to him for example.)

  2. Bobs message (the PRNG seed) is "locked" using Alice's public key and the locked message is sent to Alice. Only the private key can unlock the locked message.

  3. Alice can unlock the message using her private key. Now both Alice and Bob have a shared secret (the seed to the PRNG.)

  4. All remaining communication is done using a stream or block cipher that has been initialized to the same seed on both ends.

cipher.c

#include <stdio.h>
#include <stdlib.h>

// A stream cipher in "3" lines of code:

int main(int argc, char *argv[])
{
  int ch;
  if (argc < 2) {
    fprintf(stderr,"Usage: cipher <key>\n");
    exit(0);
  }
  srand(atoi(argv[1])); // srand() seeds the PRNG using the key value.

  while((ch = getchar()) != EOF)
    putchar(ch ^ (rand() & 0xFF));

  return 0;
}


Note: The above is a terrible stream cipher, as it uses a pretty low end PRNG. Cryptographically secure PRNGs (stream ciphers) should have the following characteristics:

  1. Large periods before the sequence of random numbers begins repeating. It should have not have as a possibility of small periods.
/**
 * Some functions that would demonstrate how one might use a stream cipher at a
 * very low level.  You probably shouldn't use these, unless you replace rand()
 * with a cryptographically secure PRNG.
 */
void combobulate(uint8_t *buf, size_t length)
{
  for(int i=0; i < length; i++)
    buf[i] ^= (rand()&0xFF);
}

ssize_t enc_read(int fd, void *buf, size_t size)
{
  int r = read(fd, buf, size);
  if (r > 0) combubulate(buf, r);
  return r;
}

ssize_t enc_write(int fd, void *buf, size_t size)
{
  combubulate(buf, size);
  return write(fd, buf, size);
}

/**
 * For multiple connections. Each connection would have it's own random state
 * saved as a pointer to rstate, which can be passed to the PRNG, in this case
 * the re-entrant version of rand(), rand_r().
 */
void combobulate(int *rstate, uint8_t *buf, size_t length)
{
  for(int i=0; i < length; i++)
    buf[i] ^= (rand_r(rstate)&0xFF);
}

Terms:

CA Certificate Authority
SSL Secure Socket Layer
TLS Transport Layer Security

SSL (Public Key) Certificates:

  • A certificate is a certificate of identity for a host that contains among other information:

    • A serial number for this particular certificate (used to identify certs that have been revoked, maintained by the CA)
    • The subjects name (usually the fully qualified host/domain name for the machine.)
    • Validity dates (range that the cert is valid for.)
    • The subjects public key (used for key exchange.)
    • The issuer of the certificate (the CA)
    • The signature of the issuer and the algorithm used to sign it.
  • The signature is the above information (a-e) encrypted using the issuers private key which may then be deciphered only using the issuers pubic key then verified with the above.

  • If we trust the certificate issuer, then we after we verify the certificate is legitimate by using the issuers public key (usually already pre-installed in our web-browsers or operating systems,) then we can trust that the host we're communicating with is the actual owner of the certificate and we can begin key-exchange with it using the public key found in the certificate.