Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
component:data [2020/01/05 02:32]
is2511 [Tier 3 Callbacks] duplicate "generated", extra dot, second "and" -> ","
component:data [2021/02/07 10:05]
tshaw [Examples]
Line 9: Line 9:
  
 - `crc32(data:​string):​string`  ​ - `crc32(data:​string):​string`  ​
-  Computes CRC-32 hash of the data. Result is in binary format+  Computes CRC-32 hash of the data. Result is in binary format.
 - `decode64(data:​string):​string`  ​ - `decode64(data:​string):​string`  ​
   Applies base64 decoding to the data.   Applies base64 decoding to the data.
 - `encode64(data:​string):​string`  ​ - `encode64(data:​string):​string`  ​
-  Applies base64 encoding to the data.+  Applies base64 encoding to the data. Result is in binary format.
 - `md5(data:​string):​string`  ​ - `md5(data:​string):​string`  ​
   Computes MD5 hash of the data. Result is in binary format   Computes MD5 hash of the data. Result is in binary format
Line 53: Line 53:
 - `deserializeKey(data:​string,​ type:​string):​table`  ​ - `deserializeKey(data:​string,​ type:​string):​table`  ​
   Transforms a key from string to it's arbitrary type.   Transforms a key from string to it's arbitrary type.
- 
 ---- ----
  
 +Examples
 +----------------
 +This card can be used to transmit encrypted data to other in-game or real-life peers. Since we are given the ability to create key-pairs and Diffie-Hellman shared keys, we are able to establish encrypted connections with these peers.
 +
 +When using key pairs for encryption, the basic concept is this
 +
 +Preliminary Setup:
 +  * (The following items are to be done on the RECEIVER)
 +  * Generate a public key (rPublic) and private key (rPrivate).
 +  * *\*If no automated key exchange, then you'll need to send rPublic to the SENDER manually.
 +
 +The SENDER must:
 +  * Read the RECEIVER'​s public key (rPublic), unserialize it, and rebuild the key object.
 +  * Generate a public key (sPublic) and private key (sPrivate).
 +  * *Generate an encryption key using rPublic and sPrivate.
 +  * Generate an Initialization Vector (IV).
 +  * Convert sPublic into a string with sPublic.serialize().
 +  * Serialize the data using the serialization library, then encrypt it using the encryption key and IV.
 +  * Serialize and transmit the message, with sPublic and IV in plain-text.
 +
 +The RECEIVER must:
 +  * Read the RECEIVER'​s private key (rPrivate), unserialize it, and rebuild the key object.
 +  * Receive the message and unserialize it using the serialization library, then deserialize sPublic using data.deserializeKey().
 +  * *Generate a decryption key using sPublic and rPrivate.
 +  * Use the decryption key, along with the IV, to decrypt the message.
 +  * Unserialize the decrypted data.
 +
 +**NOTE*** In the above, the terms '​encryption key' and '​decryption key' are used. These keys are, byte-for-byte,​ the same. This is because both keys were generated using the `ecdh()` function.
 +
 +**NOTE**** In the above, it is stated that //you will manually transfer rPublic to SENDER//. This would not be the case in systems that employ a handshake protocol. For example, SENDER would make themselves known to RECEIVER, who will then reply to SENDER with a public key (and possibly additional information,​ such as key-length). For simplicity, the following examples will not cover the functions of handshake protocols.
 +
 +To send an encrypted message:
 +```lua
 +local serialization ​ = require("​serialization"​)
 +local component ​     = require("​component"​)
 +
 +-- This table contains the data that will be sent to the receiving computer.
 +-- Along with header information the receiver will use to decrypt the message.
 +local __packet =
 +{
 +    header =
 +    {
 +        sPublic ​   = nil,
 +        iv         = nil
 +    },
 +
 +    data = nil
 +}
 +
 +-- Read the public key file.
 +local file = io.open("​rPublic","​rb"​)
 +
 +local rPublic = file:​read("​*a"​)
 +
 +file:​close()
 +
 +-- Unserialize the public key into binary form.
 +local rPublic = serialization.unserialize(rPublic)
 +
 +-- Rebuild the public key object.
 +local rPublic = component.data.deserializeKey(rPublic,"​ec-public"​)
 +
 +-- Generate a public and private keypair for this session.
 +local sPublic, sPrivate = component.data.generateKeyPair(384)
 +
 +-- Generate an encryption key.
 +local encryptionKey = component.data.md5(component.data.ecdh(sPrivate,​ rPublic))
 +
 +-- Set the header value '​iv'​ to a randomly generated 16 digit string.
 +__packet.header.iv = component.data.random(16)
 +
 +-- Set the header value '​sPublic'​ to a string.
 +__packet.header.sPublic = sPublic.serialize()
 +
 +-- The data that is to be encrypted.
 +__packet.data = "lorem ipsum"
 +
 +-- Data is serialized and encrypted.
 +__packet.data = component.data.encrypt(serialization.serialize(__packet.data),​ encryptionKey,​ __packet.header.iv)
 +
 +-- For simplicity, in this example the computers are using a Linked Card (ocdoc.cil.li/​item:​linked_card)
 +component.tunnel.send(serialization.serialize(__packet))
 +```
 +To receive the encrypted message:
 +```lua
 +local serialization = require("​serialization"​)
 +local component ​    = require("​component"​)
 +local event         = require("​event"​)
 +
 +-- Read the private key
 +local file = io.open("​rPrivate","​rb"​)
 +
 +local rPrivate = file:​read("​*a"​)
 +
 +file:​close()
 +
 +-- Unserialize the private key
 +local rPrivate = serialization.unserialize(rPrivate)
 +
 +-- Rebuild the private key object
 +local rPrivate = component.data.deserializeKey(rPrivate,"​ec-private"​)
 +
 +-- Use event.pull() to receive the message from SENDER.
 +local _, _, _, _, _, message = event.pull("​modem_message"​)
 +
 +-- Unserialize the message
 +local message = serialization.unserialize(message)
 +
 +-- From the message, deserialize the public key.
 +local sPublic = component.data.deserializeKey(message.header.sPublic,"​ec-public"​)
 +
 +-- Generate the decryption key.
 +local decryptionKey = component.data.md5(component.data.ecdh(rPrivate,​ sPublic))
 +
 +-- Use the decryption key and the IV to decrypt the encrypted data in message.data
 +local data = component.data.decrypt(message.data,​ decryptionKey,​ message.header.iv)
 +
 +-- Unserialize the decrypted data.
 +local data = serialization.unserialize(data)
 +
 +-- Print the decrypted data.
 +print(data)
 +```
 +
 +----
 {{page>​component:​contents&​noheader&​noeditbutton&​nouser&​nofooter}} {{page>​component:​contents&​noheader&​noeditbutton&​nouser&​nofooter}}