This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
component:data:zh [2023/10/24 10:04] hfsr [2级回调函数] |
component:data:zh [2023/12/10 15:35] (current) hfsr [样例] |
||
---|---|---|---|
Line 9: | Line 9: | ||
- `crc32(data:string):string` | - `crc32(data:string):string` | ||
- | 计算数据的CRC-32哈希值。结果为二进制格式。 | + | 计算数据的CRC-32哈希值。结果为二进制格式。 |
+ | \\ | ||
- `decode64(data:string):string` | - `decode64(data:string):string` | ||
- | 对数据进行base64解码。 | + | 对数据进行base64解码。 |
+ | \\ | ||
- `encode64(data:string):string` | - `encode64(data:string):string` | ||
- | 对数据进行base64编码。结果为二进制格式。 | + | 对数据进行base64编码。结果为二进制格式。 |
+ | \\ | ||
- `md5(data:string):string` | - `md5(data:string):string` | ||
- | 计算数据的MD5哈希值。结果为二进制格式。 | + | 计算数据的MD5哈希值。结果为二进制格式。 |
+ | \\ | ||
- `sha256(data:string):string` | - `sha256(data:string):string` | ||
- | 计算数据的SHA2-256哈希值。结果为二进制格式。 | + | 计算数据的SHA2-256哈希值。结果为二进制格式。 |
+ | \\ | ||
- `deflate(data:string):string` | - `deflate(data:string):string` | ||
- | 对数据用deflate算法压缩。 | + | 将数据用deflate算法压缩。 |
+ | \\ | ||
- `inflate(data:string):string` | - `inflate(data:string):string` | ||
- | 对数据用infalte算法解压。 | + | 将数据用infalte算法解压。 |
+ | \\ | ||
- `getLimit():number` | - `getLimit():number` | ||
- | 返回单次可被传递给此扩展卡其他函数的最大数据大小。 | + | 返回单次最大可传递给此扩展卡其他函数多少数据。 |
2级回调函数 | 2级回调函数 | ||
Line 29: | Line 36: | ||
- `encrypt(data:string, key:string, iv:string):string` | - `encrypt(data:string, key:string, iv:string):string` | ||
- | 使用给定密钥以及初始向量IV(最好为随机)对数据进行AES加密。 | + | 使用给定密钥以及初始向量IV(最好为随机)对数据进行AES加密。 |
+ | \\ | ||
- `decrypt(data:string, key:string, iv:string):string` | - `decrypt(data:string, key:string, iv:string):string` | ||
- | 使用给定密钥以及初始向量IV对数据进行AES解密。 | + | 使用给定密钥以及初始向量IV对数据进行AES解密。 |
+ | \\ | ||
- `random(len:number):string` | - `random(len:number):string` | ||
生成长度为 `len` 的随机二进制字符串。 | 生成长度为 `len` 的随机二进制字符串。 | ||
- | Tier 3 Callbacks | + | 3级回调函数 |
---------------- | ---------------- | ||
- `generateKeyPair([bitLen:number]):table, table` | - `generateKeyPair([bitLen:number]):table, table` | ||
- | Generates a public/private key pair for various cryptiographic functions. | + | 生成一对可用于多种加密算法的公钥与私钥。可选的第二个参数代表密钥长度,值可为256或384。 |
- | Optional second parameter specifies key length, 256 or 384 bits accepted. | + | 密钥类型包括"ec-public"和"ec-private"。密钥可以使用`key.serialize():string`来序列化。密钥中还包含一个函数`key.isPublic():boolean`。 |
- | Key types include "ec-public" and "ec-private". Keys can be serialized with | + | \\ |
- | `key.serialize():string` Keys also contain the function `key.isPublic():boolean` | + | |
- `ecdsa(data:string, key:userdata[, sig:string]):string or boolean` | - `ecdsa(data:string, key:userdata[, sig:string]):string or boolean` | ||
- | Generates a signiture of data using a private key. If signature is present | + | 不给定签名则使用给定私钥生成数据的一份签名。若给定了签名则功能为使用公钥、先前生成的签名字符串以及原字符串校验签名。 |
- | verifies the signature using the public key, the previously generated | + | \\ |
- | signature string and the original string. | + | |
- `ecdh(privateKey:userdata, publicKey:userdata):string` | - `ecdh(privateKey:userdata, publicKey:userdata):string` | ||
- | Generates a Diffie-Hellman shared key using the first user's private key and | + | 使用第一个参数给出的用户私钥与第二个参数给出的用户公钥,生成一个Diffie-Hellman共享密钥。密钥基本关系的示例为: |
- | the second user's public key. An example of a basic key relation: | + | `ecdh(userA.private, userB.public) == ecdh(userB.private, userA.public)` |
- | `ecdh(userA.private, userB.public) == ecdh(userB.private, userA.public)` | + | \\ |
- `deserializeKey(data:string, type:string):table` | - `deserializeKey(data:string, type:string):table` | ||
- | 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. | + | 此扩展卡可用于向其他在游戏中或在现实中的人发送加密数据。既然我们有能力创建密钥对和Diffie-Hellman共享密钥,那么我们就可以与这些人建立加密连接。 |
- | 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). | + | * 生成一个公钥(`rPublic`)与一个私钥(`rPrivate`)。 |
- | * *\*If no automated key exchange, then you'll need to send rPublic to the SENDER manually. | + | * \*\*若不能进行自动密钥交换,则你需要将`rPublic`手动传给**发送者**。 |
- | The SENDER must: | + | **发送者**必须: |
- | * *\*\*Read the RECEIVER's public key (rPublic), unserialize it, and rebuild the key object. | + | * \*\*\*读取**接收者**的公钥(`rPublic`),将其解序列化并重构出密钥对象。 |
- | * Generate a public key (sPublic) and private key (sPrivate). | + | * 生成一个公钥(`sPublic`)和一个私钥(`sPrivate`)。 |
- | * *Generate an encryption key using rPublic and sPrivate. | + | * \*用`rPublic`和`sPrivate`生成加密密钥。 |
- | * Generate an Initialization Vector (IV). | + | * 生成一个初始向量(IV)。 |
- | * Convert sPublic into a string with sPublic.serialize(). | + | * 使用`sPublic.serialize()`将`sPublic`转化为字符串 |
- | * *\*\*Serialize the data using the serialization library, then encrypt it using the encryption key and IV. | + | * *\*\*用serialization(序列化)库将数据序列化,然后使用加密密钥和IV将其加密。 |
- | * Serialize and transmit the message, with sPublic and IV in plain-text. | + | * 序列化并发送信息,其中有明文形式的`sPublic`与IV。 |
- | The RECEIVER must: | + | **接收者**必须: |
- | * Read the RECEIVER's private key (rPrivate), unserialize it, and rebuild the key object. | + | * 读取**发送者**的私钥(`rPrivate`),将其解序列化并重构出密钥对象。 |
- | * Receive the message and unserialize it using the serialization library, then deserialize sPublic using data.deserializeKey(). | + | * 接收信息,并使用serialization(序列化)运行库将其解序列化。然后使用`data.deserializeKey()`解序列化`sPublic`。 |
- | * *Generate a decryption key using sPublic and rPrivate. | + | * \*使用`sPublic`和`rPrivate`生成解密密钥。 |
- | * Use the decryption key, along with the IV, to decrypt the message. | + | * 使用解密密钥和IV来解密信息。 |
- | * 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. | + | **注\*:**上文中使用了“加密密钥”和“解密密钥”两个术语。这两个密钥完全相同,因为这两个密钥都是使用`ecdh()`函数生成的。 |
- | **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. | + | **注\*\*:**上文说“你需要将`rPublic`手动传给**发送者**”。但是在使用握手协议的系统中情况并非如此。例如,**发送者**会让**接收者**知道自己的存在,然后**接收者**会回复给**发送者**一个公钥(可能还有附加信息,例如密钥长度)。为简单起见,以下示例不涵盖握手协议的功能。 |
- | **NOTE***** The examples above and below state that you must serialize/unserialize a key or message. In-general, it is good practice to serialize data (especially when in binary format) before you write it to a file, or transfer it on the network. Serialization makes sure that the binary data is 'escaped', making it safe for your script or shell to read. | + | **注\*\*\*:**上文与下文的示例提到需要将密钥和信息序列化/解序列化。总体来说,在你将数据(尤其是二进制形式的)写入文件或通过网络传输前对其序列化是有益的。序列化能保证二进制数据“有结尾”,使你的脚本或shell读取时更加安全。 |
- | To send an encrypted message: | + | 若要发送加密数据: |
```lua | ```lua | ||
local serialization = require("serialization") | local serialization = require("serialization") | ||
local component = require("component") | 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 = | local __packet = | ||
{ | { | ||
Line 106: | Line 112: | ||
} | } | ||
- | -- Read the public key file. | + | --读取公钥文件。 |
local file = io.open("rPublic","rb") | local file = io.open("rPublic","rb") | ||
Line 113: | Line 119: | ||
file:close() | file:close() | ||
- | -- Unserialize the public key into binary form. | + | --将公钥解序列化为二进制形式。 |
local rPublic = serialization.unserialize(rPublic) | local rPublic = serialization.unserialize(rPublic) | ||
- | -- Rebuild the public key object. | + | --重建公钥对象。 |
local rPublic = component.data.deserializeKey(rPublic,"ec-public") | local rPublic = component.data.deserializeKey(rPublic,"ec-public") | ||
- | -- Generate a public and private keypair for this session. | + | --为此会话生成一个公钥与一个私钥。 |
local sPublic, sPrivate = component.data.generateKeyPair(384) | local sPublic, sPrivate = component.data.generateKeyPair(384) | ||
- | -- Generate an encryption key. | + | --生成一个加密密钥。 |
local encryptionKey = component.data.md5(component.data.ecdh(sPrivate, rPublic)) | local encryptionKey = component.data.md5(component.data.ecdh(sPrivate, rPublic)) | ||
- | -- Set the header value 'iv' to a randomly generated 16 digit string. | + | --将信息头中值'iv'设定为一个随机生成的16位数字字符串。 |
__packet.header.iv = component.data.random(16) | __packet.header.iv = component.data.random(16) | ||
- | -- Set the header value 'sPublic' to a string. | + | --将信息头中值'sPublic'设定为一个字符串。 |
__packet.header.sPublic = sPublic.serialize() | __packet.header.sPublic = sPublic.serialize() | ||
- | -- The data that is to be encrypted. | + | --待加密的数据。 |
__packet.data = "lorem ipsum" | __packet.data = "lorem ipsum" | ||
- | -- Data is serialized and encrypted. | + | --数据被序列化并被加密了。 |
__packet.data = component.data.encrypt(serialization.serialize(__packet.data), encryptionKey, __packet.header.iv) | __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) | + | --为简单起见,此样例中的电脑使用连接卡(ocdoc.cil.li/item:linked_card:zh) |
component.tunnel.send(serialization.serialize(__packet)) | component.tunnel.send(serialization.serialize(__packet)) | ||
``` | ``` | ||
- | To receive the encrypted message: | + | 若要接收加密数据: |
```lua | ```lua | ||
local serialization = require("serialization") | local serialization = require("serialization") | ||
Line 146: | Line 152: | ||
local event = require("event") | local event = require("event") | ||
- | -- Read the private key | + | --读取私钥。 |
local file = io.open("rPrivate","rb") | local file = io.open("rPrivate","rb") | ||
Line 153: | Line 159: | ||
file:close() | file:close() | ||
- | -- Unserialize the private key | + | --将私钥解序列化。 |
local rPrivate = serialization.unserialize(rPrivate) | local rPrivate = serialization.unserialize(rPrivate) | ||
- | -- Rebuild the private key object | + | --重建私钥对象。 |
local rPrivate = component.data.deserializeKey(rPrivate,"ec-private") | local rPrivate = component.data.deserializeKey(rPrivate,"ec-private") | ||
- | -- Use event.pull() to receive the message from SENDER. | + | --使用event.pull()以接收来自发送者的信息。 |
local _, _, _, _, _, message = event.pull("modem_message") | local _, _, _, _, _, message = event.pull("modem_message") | ||
- | -- Unserialize the message | + | --将信息解序列化。 |
local message = serialization.unserialize(message) | local message = serialization.unserialize(message) | ||
- | -- From the message, deserialize the public key. | + | --从信息中获取公钥并解序列化。 |
local sPublic = component.data.deserializeKey(message.header.sPublic,"ec-public") | local sPublic = component.data.deserializeKey(message.header.sPublic,"ec-public") | ||
- | -- Generate the decryption key. | + | --生成解密密钥。 |
local decryptionKey = component.data.md5(component.data.ecdh(rPrivate, sPublic)) | 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 | + | --使用解密密钥和IV来解密message.data中的加密数据 |
local data = component.data.decrypt(message.data, decryptionKey, message.header.iv) | local data = component.data.decrypt(message.data, decryptionKey, message.header.iv) | ||
- | -- Unserialize the decrypted data. | + | --解序列化解密后的数据。 |
local data = serialization.unserialize(data) | local data = serialization.unserialize(data) | ||
- | -- Print the decrypted data. | + | --输出解密后的数据。 |
print(data) | print(data) | ||
``` | ``` |