Encrytion and Decryption

https://cran.r-project.org/web/packages/sodium/vignettes/crypto101.html.

https://cran.r-project.org/web/packages/sodium/vignettes/intro.html#secret-key-encryption.

Encryption is the process of turning a clear-text message (Plaintext) into a data stream which looks like a meaningless and random sequence of bits (ciphertext). The process of turning ciphertext back into plaintext is called decryption.

Cryptography deals with making communications secure.

Cryptoanalysis deals with breaking ciphertext, that is, recovering plaintext without knowing the key.

Cryptology is a branch of mathematics which deals with both cryptography and cryptoanalysis.

A cryptographic algorithm, also known as a cipher, is a mathematical function which uses plaintext as the input and produces ciphertext as the output and vice versa.

All modern ciphers use keys together with plaintext as the input to produce ciphertext. The same or a different key is supplied to the decryption function to recover plaintext from ciphertext. The details of a cryptographic algorithm are usually made public. It is the key that the security of a modern cipher lies in, not the details of the cipher.

Symmetric algorithms use the same key for encryption and decryption. These algorithms require that both the sender and receiver agree on a key before they can exchange messages securely.

Some symmetric algorithms operate on 1 bit (or sometimes 1 byte) of plaintext at a time. They are called stream ciphers. Other algorithms operate on blocks of bits at a time. They are called block ciphers. Most modern block ciphers use the block size of 64 bits.

Public-key algorithms (also known as asymmetric algorithms) use two different keys (a key pair) for encryption and decryption. The keys in a key pair are mathematically related, but it is computationally infeasible to deduce one key from the other. These algorithms are called “public-key” because the encryption key can be made public. Anyone can use the public key to encrypt a message, but only the owner of the corresponding private key can decrypt it.

Some public-key algorithms such as RSA allow the process to work in the opposite direction as well: a message can be encrypted with a private key and decrypted with the corresponding public key. If Alice (or anyone else) can decrypt a message with Bob’s public key she knows that the message must have come from Bob because no one else has Bob’s private key.

Symmetric Encryption

Symmetric encryption is the backbone of any secure communication system. Dozens of symmetric algorithms have been invented and impemented, both in hardware and software.

One-way Hash Function

A one-way hash function, also known as a message digest, fingerprint or compression function, is a mathematical function which takes a variable-length input string and converts it into a fixed-length binary sequence. Furthermore, a one-way hash function is designed in such a way that it is hard to reverse the process, that is, to find a string that hashes to a given value (hence the name one-way.) A good hash function also makes it hard to find two strings that would produce the same hash value. All modern hash algorithms produce hash values of 128 bits and higher.

Public-Key Cryptography

Unlike symmetric cryptography, public key cryptography uses two different keys - one public and one private. The keys are mathematically related, yet it is computationally infeasible to deduce one from the other. Anyone with the public key can encrypt a message but not decrypt it. Only the person with the private key can decrypt the message.

Bruce Schneier compares public-key cryptography with a mailbox. He writes:

“Putting mail in the mailbox is analogous to encrypting with the public key; anyone can do it. Just open the slot and drop it in. Getting mail out of a mailbox is analogous to decrypting with the private key. Generally it’s hard; you need welding torches. However, if you have the secret (the physical key to the mailbox), it’s easy to get mail out of a mailbox.”

Digital Certificates

A certificate is a data package that completely identifies an entity, and is issued by a Certification Authority (CA) only after that authority has verified the entity’s identity. The data package includes the public key that belongs to the entity. When the sender of a message signs the message with its private key, the recipient of the message can use the sender’s public key (retrieved from the certificate either sent with the message or available elsewhere on the network) to verify that the sender is legitimate.

http://www.itu.int/itu-t/recommendations/rec.aspx?rec=X.509.

Basic Tools

Character to Raw Bit Data

library(openssl)
## Warning: package 'openssl' was built under R version 3.4.3
library(sodium)
## Warning: package 'sodium' was built under R version 3.4.3
## 
## Attaching package: 'sodium'
## The following objects are masked from 'package:openssl':
## 
##     sha256, sha512
x1 = charToRaw("Hello, my name is Janpu HOu")
x1
##  [1] 48 65 6c 6c 6f 2c 20 6d 79 20 6e 61 6d 65 20 69 73 20 4a 61 6e 70 75
## [24] 20 48 4f 75
y1 = rawToChar(x1)
y1
## [1] "Hello, my name is Janpu HOu"
z1 = hash(x1)
z1
##  [1] f4 60 c0 39 6a bf 1b e4 f6 32 87 d5 d9 e8 c2 f1 88 c8 3e 3a 97 d8 62
## [24] f5 64 2b c9 ab c7 88 30 2e
str <- bin2hex(z1)
print(str)
## [1] "f460c0396abf1be4f63287d5d9e8c2f188c83e3a97d862f5642bc9abc788302e"
z2 = hex2bin(str)

Random Number Generator

The random() function generates n bytes of unpredictable data, suitable for creating secret keys.

secret <- random(27)
print(secret)
##  [1] 62 a6 44 8b 94 58 4a d6 d5 b5 8e 6a 48 c3 1d 35 26 44 04 8d b7 25 56
## [24] 64 4c d0 a8

Hash functions

# Generate keys from Password
passphrase <- charToRaw("This is my super secret password")
hash(passphrase)
##  [1] 32 47 07 cf 2d d2 64 22 9e 7e cc 66 fa 92 29 2d ad d7 62 84 b6 d4 d9
## [24] 7f 6b f2 67 d9 7e 3d 4e c4
hash(passphrase, size = 16)
##  [1] 88 00 42 12 78 26 bd e8 2c 98 e5 3c ef 05 bf b0
hash(passphrase, size = 64)
##  [1] d1 59 65 f8 e3 b2 4f f4 fe a1 ba 12 0d 64 61 37 cc 8d 81 ab 4e 89 79
## [24] 12 67 25 5d 91 e9 26 4d 65 78 d3 19 20 2f a1 15 53 41 94 81 94 51 4b
## [47] c6 3d 77 ef 8e 84 41 a7 fb 47 73 5b a7 30 bb ed 8f 5f

Plaintext and Ciphertext

library(seqinr)
## Warning: package 'seqinr' was built under R version 3.4.3
message <- "Hello, my name is Janpu Hou"
message
## [1] "Hello, my name is Janpu Hou"
ciphertext <- rot13(message)
ciphertext
## [1] "Uryyb, zl anzr vf Wnach Ubh"
plaintext <- rot13(ciphertext)
plaintext
## [1] "Hello, my name is Janpu Hou"

Symmetric Encryption

Secret key Encryption

Symmetric encryption uses the same secret key for both encryption and decryption. It is mainly useful for encrypting local data, or as a building block for more complex methods.

Most encryption methods require a nonce: a piece of non-secret unique data that is used to randomize the cipher. This allows for safely using the same key for encrypting multiple messages. The nonce should be stored or shared along with the ciphertext.

Because the secret has to be known by all parties, symmetric encryption by itself is often impractical for communication with third parties. For this we need asymmetric (public key) methods.

key <- hash(charToRaw("This is a secret passphrase"))
msg <- serialize(iris, NULL)

# Encrypt with a random nonce
nonce <- random(24)
cipher <- data_encrypt(msg, key, nonce)

# Decrypt with same key and nonce
orig <- data_decrypt(cipher, key, nonce)
identical(iris, unserialize(orig))
## [1] TRUE

Secret Key Authentication

Secret key authentication is called tagging in Sodium. A tag is basically a hash of the data together with a secret key.

key <- hash(charToRaw("This is a secret passphrase"))
msg <- serialize(iris, NULL)
mytag <- data_tag(msg, key)

# To verify the integrity of the data at a later point in time, simply re-calculate the tag with the same key:

identical(mytag, data_tag(msg, key))
## [1] TRUE
stopifnot(identical(mytag, data_tag(msg, key)))

# The secret key protects against forgery of the data+tag by an intermediate party, as would be possible with a regular checksum.

Asymmetric Encryption

Public key encryption

Where symmetric methods use the same secret key for encryption and decryption, asymmetric methods use a key-pair consisting of a public key and private key. The private key is secret and only known by its owner. The public key on the other hand can be shared with anyone. Public keys are often published on the user’s website or posted in public directories or keyservers.

key <- keygen()
pub <- pubkey(key)

In public key encryption, data encrypted with a public key can only be decrypted using the corresponding private key. This allows anyone to send somebody a secure message by encrypting it with the receivers public key. The encrypted message will only be readable by the owner of the corresponding private key.

# Encrypt message with pubkey
head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa
msg <- serialize(iris, NULL)
head(msg,200)
##   [1] 58 0a 00 00 00 02 00 03 04 01 00 02 03 00 00 00 03 13 00 00 00 05 00
##  [24] 00 00 0e 00 00 00 96 40 14 66 66 66 66 66 66 40 13 99 99 99 99 99 9a
##  [47] 40 12 cc cc cc cc cc cd 40 12 66 66 66 66 66 66 40 14 00 00 00 00 00
##  [70] 00 40 15 99 99 99 99 99 9a 40 12 66 66 66 66 66 66 40 14 00 00 00 00
##  [93] 00 00 40 11 99 99 99 99 99 9a 40 13 99 99 99 99 99 9a 40 15 99 99 99
## [116] 99 99 9a 40 13 33 33 33 33 33 33 40 13 33 33 33 33 33 33 40 11 33 33
## [139] 33 33 33 33 40 17 33 33 33 33 33 33 40 16 cc cc cc cc cc cd 40 15 99
## [162] 99 99 99 99 9a 40 14 66 66 66 66 66 66 40 16 cc cc cc cc cc cd 40 14
## [185] 66 66 66 66 66 66 40 15 99 99 99 99 99 9a 40 14
ciphertext <- simple_encrypt(msg, pub)
head(ciphertext,200)
##   [1] b2 06 3a 53 e0 8a cc f0 34 74 cf d1 eb fe 64 db 13 21 dd d1 7a e4 01
##  [24] e4 db 75 f1 54 08 91 0a 2d 9c c2 93 e9 f8 d4 b1 03 85 71 75 6e 75 d0
##  [47] 97 e0 a6 61 d9 52 90 62 12 f1 a3 09 c7 73 45 a6 28 0e 5c b6 9c e1 37
##  [70] 5e b6 ca f9 9e 61 bb a6 f7 13 3b ad 66 78 04 cb 68 a0 ad 99 39 05 9b
##  [93] da 76 8f 5b ca a7 17 9d e6 3b 58 f5 a0 ff af 44 02 f3 ed f1 a9 fb 82
## [116] 6e 44 0f 60 12 bb 1f 2e f5 4f be 3c 3a 08 12 03 55 b8 16 f0 11 f7 7c
## [139] 07 18 59 15 e7 77 a9 c7 cc 92 f6 8c 53 e3 38 e9 7f a6 a6 a9 fa 68 ff
## [162] 32 44 69 0f 8e e1 05 66 35 b5 b4 66 b1 d6 4f 21 13 63 dc b9 fd 38 ad
## [185] e5 50 e7 73 e6 6a ec e8 8d e1 6a 4e b3 2a 6c 66
# Decrypt message with private key
out <- simple_decrypt(ciphertext, key)
head(out,200)
##   [1] 58 0a 00 00 00 02 00 03 04 01 00 02 03 00 00 00 03 13 00 00 00 05 00
##  [24] 00 00 0e 00 00 00 96 40 14 66 66 66 66 66 66 40 13 99 99 99 99 99 9a
##  [47] 40 12 cc cc cc cc cc cd 40 12 66 66 66 66 66 66 40 14 00 00 00 00 00
##  [70] 00 40 15 99 99 99 99 99 9a 40 12 66 66 66 66 66 66 40 14 00 00 00 00
##  [93] 00 00 40 11 99 99 99 99 99 9a 40 13 99 99 99 99 99 9a 40 15 99 99 99
## [116] 99 99 9a 40 13 33 33 33 33 33 33 40 13 33 33 33 33 33 33 40 11 33 33
## [139] 33 33 33 33 40 17 33 33 33 33 33 33 40 16 cc cc cc cc cc cd 40 15 99
## [162] 99 99 99 99 9a 40 14 66 66 66 66 66 66 40 16 cc cc cc cc cc cd 40 14
## [185] 66 66 66 66 66 66 40 15 99 99 99 99 99 9a 40 14
head(msg,200)
##   [1] 58 0a 00 00 00 02 00 03 04 01 00 02 03 00 00 00 03 13 00 00 00 05 00
##  [24] 00 00 0e 00 00 00 96 40 14 66 66 66 66 66 66 40 13 99 99 99 99 99 9a
##  [47] 40 12 cc cc cc cc cc cd 40 12 66 66 66 66 66 66 40 14 00 00 00 00 00
##  [70] 00 40 15 99 99 99 99 99 9a 40 12 66 66 66 66 66 66 40 14 00 00 00 00
##  [93] 00 00 40 11 99 99 99 99 99 9a 40 13 99 99 99 99 99 9a 40 15 99 99 99
## [116] 99 99 9a 40 13 33 33 33 33 33 33 40 13 33 33 33 33 33 33 40 11 33 33
## [139] 33 33 33 33 40 17 33 33 33 33 33 33 40 16 cc cc cc cc cc cd 40 15 99
## [162] 99 99 99 99 9a 40 14 66 66 66 66 66 66 40 16 cc cc cc cc cc cd 40 14
## [185] 66 66 66 66 66 66 40 15 99 99 99 99 99 9a 40 14
identical(out,msg)
## [1] TRUE
stopifnot(identical(out, msg))

Public key authentication (signatures)

Public key authentication works the other way around. First, the owner of the private key creates a ‘signature’ (an authenticated checksum) for a message in a way that allows anyone who knows his/her public key to verify the integrity of the message and identity of the sender.

Currently sodium requires a different type of key-pair for signatures (ed25519) than for encryption (curve25519).

# Generate signature keypair
key <- sig_keygen()
pubkey <- sig_pubkey(key)

# Create signature with private key
msg <- serialize(iris, NULL)
sig <- sig_sign(msg, key)
print(sig)
##  [1] b8 5e 2a 74 af a4 64 8e 3f 7a 1f f5 8f 60 ef 6a f2 1a 8f 64 97 01 e7
## [24] 36 29 b0 fc 9b 89 f9 6e c2 cc 43 73 9c 45 50 9c cd 4e 2d ba 59 ba c4
## [47] d9 a6 7f 20 36 07 21 33 17 1f e8 f7 28 21 3c 7d f8 05

Verify a signature from public key

sig_verify(msg, sig, pubkey)
## [1] TRUE

Signatures are useful when the message itself is not confidential but integrity is important. A common use is for software repositories where to include an index file with checksums for all packages, signed by the repository maintainer. This allows client package managers to verify that the binaries were not manipulated by intermediate parties during the distribution process.

Public key authenticated encryption

Authenticated encryption implements best practices for secure messaging. It requires that both sender and receiver have a keypair and know each other’s public key. Each message gets authenticated with the key of the sender and encrypted with the key of the receiver.

# Bob's keypair:
bob_key <- keygen()
bob_pubkey <- pubkey(bob_key)

# Alice's keypair:
alice_key <- keygen()
alice_pubkey <- pubkey(alice_key)

# Bob sends encrypted message for Alice:
msg <- charToRaw("TTIP is evil")
ciphertext <- auth_encrypt(msg, bob_key, alice_pubkey)

# Alice verifies and decrypts with her key
out <- auth_decrypt(ciphertext, alice_key, bob_pubkey)
stopifnot(identical(out, msg))

# Alice sends encrypted message for Bob
msg <- charToRaw("Let's protest")
ciphertext <- auth_encrypt(msg, alice_key, bob_pubkey)

# Bob verifies and decrypts with his key
out <- auth_decrypt(ciphertext, bob_key, alice_pubkey)
stopifnot(identical(out, msg))

Digital Certificates

A certificate is a data package that completely identifies an entity, and is issued by a Certification Authority (CA) only after that authority has verified the entity’s identity. The data package includes the public key that belongs to the entity. When the sender of a message signs the message with its private key, the recipient of the message can use the sender’s public key (retrieved from the certificate either sent with the message or available elsewhere on the network) to verify that the sender is legitimate.

In cryptography, X.509 is a standard that defines the format of public key certificates. X.509 certificates are used in many Internet protocols, including TLS/SSL, which is the basis for HTTPS, the secure protocol for browsing the web. They’re also used in offline applications, like electronic signatures.

library(openssl)

# Verify the r-project HTTPS cert
chain <- download_ssl_cert("www.r-project.org", 443)
print(chain)
## [[1]]
## [x509 certificate] *.r-project.org
## md5: 9aa98308c79a93da348a6a228b2e48ab
## sha1: 35c5d904e830005b852c2c1b6e5db00773524aad
## 
## [[2]]
## [x509 certificate] Starfield Secure Certificate Authority - G2
## md5: 1cd0976187316dde07259fd6267e2f0e
## sha1: 7edc376dcfd45e6ddf082c160df6ac21835b95d4
## 
## [[3]]
## [x509 certificate] Starfield Root Certificate Authority - G2
## md5: 497bf0a8bc53a0846d7fd29499f558e9
## sha1: 9565b778c8a50eb4fefd45c8a658dde2411ead0a
## 
## [[4]]
## [x509 certificate] 
## md5: 324a4bbbc863699bbe749ac6dd1d4624
## sha1: ad7e1c28b064ef8f6003402014c3d0e3370eb58a
print(as.list(chain[[1]])$pubkey)
## [2048-bit rsa public key]
## md5: 6b372d9b5c5759fbb28baf03c609730a
cert_verify(chain, ca_bundle())
## [1] TRUE
# Another example
chain <- download_ssl_cert("public.opencpu.org")
ocpu <- chain[[1]]
as.list(ocpu)$subject
## [1] "CN=sni70697.cloudflaressl.com,OU=PositiveSSL Multi-Domain,OU=Domain Control Validated"
# Write PEM format
write_pem(ocpu)
## [1] "-----BEGIN CERTIFICATE-----\nMIIHMjCCBtigAwIBAgIQesl7KzzNn9qdphaJe96ekzAKBggqhkjOPQQDAjCBkjEL\nMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\nBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\nL0NPTU9ETyBFQ0MgRG9tYWluIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQSAy\nMB4XDTE3MTIwNjAwMDAwMFoXDTE4MDYxNDIzNTk1OVowazEhMB8GA1UECxMYRG9t\nYWluIENvbnRyb2wgVmFsaWRhdGVkMSEwHwYDVQQLExhQb3NpdGl2ZVNTTCBNdWx0\naS1Eb21haW4xIzAhBgNVBAMTGnNuaTcwNjk3LmNsb3VkZmxhcmVzc2wuY29tMFkw\nEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEHCQsg/BsYBYLBY8HgQvG2kPAPZyfA5YA\nfBidYUj+9WO0GbNqqIxcqiMgfGzxvvtwkPRmo0/cH5yvWIs75ECJW6OCBTQwggUw\nMB8GA1UdIwQYMBaAFEAJYWfwvINxT94SCCxv1NQrdj2WMB0GA1UdDgQWBBS7jE7q\npkEFUHcWWUwTs8QndpfOgDAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAd\nBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA6BgsrBgEE\nAbIxAQICBzArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21vZG8uY29t\nL0NQUzAIBgZngQwBAgEwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5jb21v\nZG9jYTQuY29tL0NPTU9ET0VDQ0RvbWFpblZhbGlkYXRpb25TZWN1cmVTZXJ2ZXJD\nQTIuY3JsMIGIBggrBgEFBQcBAQR8MHowUQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQu\nY29tb2RvY2E0LmNvbS9DT01PRE9FQ0NEb21haW5WYWxpZGF0aW9uU2VjdXJlU2Vy\ndmVyQ0EyLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AuY29tb2RvY2E0LmNv\nbTCCA3sGA1UdEQSCA3IwggNughpzbmk3MDY5Ny5jbG91ZGZsYXJlc3NsLmNvbYIW\nKi5haXJjby1vbmRlcmRlbGVuLmNvbYIVKi5haXJjb3NlcnZpY2VoZWluLm5sghgq\nLmJyYWRwZXJraW5zaW1hZ2luZy5jb22CFyouY29saWJyaXNzb2x1dGlvbnMuY29t\nghAqLmRjYmFsbHBhcmsuY29tgg8qLmRpc3RqbWhzbmQubWyCDiouZWFzeXNjb3Jl\nLmNoghIqLmZhdWNldGJpdGNvaW4ucnWCEyouaGVlcmVuc2NodWVybGkuY2iCDyou\naXBtYWNoaW5lcy5ydYIMKi5pci1wMHJuLnB3ghMqLmppYW5qaXRpYW54aWEuY29t\ngg8qLm10aGFpcmVsYXgucnWCCCoubXZrLmN4gg0qLm9wZW5jcHUub3JnggwqLm92\nZXB5YnUuZ3GCCSoucm93by5jb4IXKi5zYWdlYWR2aXNvcnlncm91cC5jb22CFSou\nc2tycnB0YmxsdWZnZGFzcy5jZoILKi5zdGFib24ucnWCFyoudG9wbW9kZWxzcGll\nbGUucmV2aWV3ghMqLndhcm5pbmctdmlydXMuY29tggwqLndwYm9va3MubWyCESou\nd3BtdWx0aXNpdGUuY29tghRhaXJjby1vbmRlcmRlbGVuLmNvbYITYWlyY29zZXJ2\naWNlaGVpbi5ubIIWYnJhZHBlcmtpbnNpbWFnaW5nLmNvbYIVY29saWJyaXNzb2x1\ndGlvbnMuY29tgg5kY2JhbGxwYXJrLmNvbYINZGlzdGptaHNuZC5tbIIMZWFzeXNj\nb3JlLmNoghBmYXVjZXRiaXRjb2luLnJ1ghFoZWVyZW5zY2h1ZXJsaS5jaIINaXBt\nYWNoaW5lcy5ydYIKaXItcDBybi5wd4IRamlhbmppdGlhbnhpYS5jb22CDW10aGFp\ncmVsYXgucnWCBm12ay5jeIILb3BlbmNwdS5vcmeCCm92ZXB5YnUuZ3GCB3Jvd28u\nY2+CFXNhZ2VhZHZpc29yeWdyb3VwLmNvbYITc2tycnB0YmxsdWZnZGFzcy5jZoIJ\nc3RhYm9uLnJ1ghV0b3Btb2RlbHNwaWVsZS5yZXZpZXeCEXdhcm5pbmctdmlydXMu\nY29tggp3cGJvb2tzLm1sgg93cG11bHRpc2l0ZS5jb20wCgYIKoZIzj0EAwIDSAAw\nRQIhAKkRZmYveCnwzEtlmqq+3I51/sX0Z244NTtDJ81A/t4nAiBqRz3h3cp/2ncx\n27ZQxwNwgl6SaVL3IhWu1QlB1dYsSQ==\n-----END CERTIFICATE-----\n"