Component/data/zh: Difference between revisions
Jump to navigation
Jump to search
imported>OCDoc Import Imported from legacy OpenComputers documentation at ocdoc.cil.li |
Clean up Markdown artifacts from DokuWiki migration |
||
| Line 3: | Line 3: | ||
此组件由[[Item/data card/zh|数据卡]]提供。 | 此组件由[[Item/data card/zh|数据卡]]提供。 | ||
组件名: | 组件名:<code>data</code>。 | ||
== 1级回调函数 == | == 1级回调函数 == | ||
* | * <code>crc32(data:string):string</code> | ||
<pre>计算数据的CRC-32哈希值。结果为二进制格式。 | <pre>计算数据的CRC-32哈希值。结果为二进制格式。 | ||
</pre> | </pre> | ||
* | * <code>decode64(data:string):string</code> | ||
<pre>对数据进行base64解码。 | <pre>对数据进行base64解码。 | ||
</pre> | </pre> | ||
* | * <code>encode64(data:string):string</code> | ||
<pre>对数据进行base64编码。结果为二进制格式。 | <pre>对数据进行base64编码。结果为二进制格式。 | ||
</pre> | </pre> | ||
* | * <code>md5(data:string):string</code> | ||
<pre>计算数据的MD5哈希值。结果为二进制格式。 | <pre>计算数据的MD5哈希值。结果为二进制格式。 | ||
</pre> | </pre> | ||
* | * <code>sha256(data:string):string</code> | ||
<pre>计算数据的SHA2-256哈希值。结果为二进制格式。 | <pre>计算数据的SHA2-256哈希值。结果为二进制格式。 | ||
</pre> | </pre> | ||
* | * <code>deflate(data:string):string</code> | ||
<pre>将数据用deflate算法压缩。 | <pre>将数据用deflate算法压缩。 | ||
</pre> | </pre> | ||
* | * <code>inflate(data:string):string</code> | ||
<pre>将数据用infalte算法解压。 | <pre>将数据用infalte算法解压。 | ||
</pre> | </pre> | ||
* | * <code>getLimit():number</code> | ||
<pre>返回单次最大可传递给此扩展卡其他函数多少数据。 | <pre>返回单次最大可传递给此扩展卡其他函数多少数据。 | ||
| Line 48: | Line 48: | ||
== 2级回调函数 == | == 2级回调函数 == | ||
* | * <code>encrypt(data:string, key:string, iv:string):string</code> | ||
<pre>使用给定密钥以及初始向量IV(最好为随机)对数据进行AES加密。 | <pre>使用给定密钥以及初始向量IV(最好为随机)对数据进行AES加密。 | ||
</pre> | </pre> | ||
* | * <code>decrypt(data:string, key:string, iv:string):string</code> | ||
<pre>使用给定密钥以及初始向量IV对数据进行AES解密。 | <pre>使用给定密钥以及初始向量IV对数据进行AES解密。 | ||
</pre> | </pre> | ||
* | * <code>random(len:number):string</code> | ||
<pre>生成长度为 | <pre>生成长度为 len 的随机二进制字符串。 | ||
</pre> | </pre> | ||
== 3级回调函数 == | == 3级回调函数 == | ||
* | * <code>generateKeyPair([bitLen:number]):table, table</code> | ||
<pre>生成一对可用于多种加密算法的公钥与私钥。可选的第二个参数代表密钥长度,值可为256或384。 | <pre>生成一对可用于多种加密算法的公钥与私钥。可选的第二个参数代表密钥长度,值可为256或384。 | ||
密钥类型包括"ec-public"和"ec-private" | 密钥类型包括"ec-public"和"ec-private"。密钥可以使用key.serialize():string来序列化。密钥中还包含一个函数key.isPublic():boolean。 | ||
</pre> | </pre> | ||
* | * <code>ecdsa(data:string, key:userdata[, sig:string]):string or boolean</code> | ||
<pre>不给定签名则使用给定私钥生成数据的一份签名。若给定了签名则功能为使用公钥、先前生成的签名字符串以及原字符串校验签名。 | <pre>不给定签名则使用给定私钥生成数据的一份签名。若给定了签名则功能为使用公钥、先前生成的签名字符串以及原字符串校验签名。 | ||
</pre> | </pre> | ||
* | * <code>ecdh(privateKey:userdata, publicKey:userdata):string</code> | ||
<pre>使用第一个参数给出的用户私钥与第二个参数给出的用户公钥,生成一个Diffie-Hellman共享密钥。密钥基本关系的示例为: | <pre>使用第一个参数给出的用户私钥与第二个参数给出的用户公钥,生成一个Diffie-Hellman共享密钥。密钥基本关系的示例为: | ||
ecdh(userA.private, userB.public) == ecdh(userB.private, userA.public) | |||
</pre> | </pre> | ||
* | * <code>deserializeKey(data:string, type:string):table</code> | ||
<pre>将密钥从字符串形式转化为其特有形式。 | <pre>将密钥从字符串形式转化为其特有形式。 | ||
| Line 94: | Line 94: | ||
* (下列工作需要'''接收者'''完成) | * (下列工作需要'''接收者'''完成) | ||
* 生成一个公钥( | * 生成一个公钥(<code>rPublic</code>)与一个私钥(<code>rPrivate</code>)。 | ||
'' \''\*若不能进行自动密钥交换,则你需要将 | '' \''\*若不能进行自动密钥交换,则你需要将<code>rPublic</code>手动传给'''发送者'''。 | ||
'''发送者'''必须: | '''发送者'''必须: | ||
'' \''\''\''读取'''接收者'''的公钥( | '' \''\''\''读取'''接收者'''的公钥(<code>rPublic</code>),将其解序列化并重构出密钥对象。 | ||
* 生成一个公钥( | * 生成一个公钥(<code>sPublic</code>)和一个私钥(<code>sPrivate</code>)。 | ||
'' \''用 | '' \''用<code>rPublic</code>和<code>sPrivate</code>生成加密密钥。 | ||
* 生成一个初始向量(IV)。 | * 生成一个初始向量(IV)。 | ||
* 使用 | * 使用<code>sPublic.serialize()</code>将<code>sPublic</code>转化为字符串 | ||
'' ''\''\''用serialization(序列化)库将数据序列化,然后使用加密密钥和IV将其加密。 | '' ''\''\''用serialization(序列化)库将数据序列化,然后使用加密密钥和IV将其加密。 | ||
* 序列化并发送信息,其中有明文形式的 | * 序列化并发送信息,其中有明文形式的<code>sPublic</code>与IV。 | ||
'''接收者'''必须: | '''接收者'''必须: | ||
* 读取'''发送者'''的私钥( | * 读取'''发送者'''的私钥(<code>rPrivate</code>),将其解序列化并重构出密钥对象。 | ||
* 接收信息,并使用serialization(序列化)运行库将其解序列化。然后使用 | * 接收信息,并使用serialization(序列化)运行库将其解序列化。然后使用<code>data.deserializeKey()</code>解序列化<code>sPublic</code>。 | ||
'' \''使用 | '' \''使用<code>sPublic</code>和<code>rPrivate</code>生成解密密钥。 | ||
* 使用解密密钥和IV来解密信息。 | * 使用解密密钥和IV来解密信息。 | ||
* 解序列化解密后的信息。 | * 解序列化解密后的信息。 | ||
'''注\*:'''上文中使用了“加密密钥”和“解密密钥”两个术语。这两个密钥完全相同,因为这两个密钥都是使用 | '''注\*:'''上文中使用了“加密密钥”和“解密密钥”两个术语。这两个密钥完全相同,因为这两个密钥都是使用<code>ecdh()</code>函数生成的。 | ||
'''注\''\'':'''上文说“你需要将 | '''注\''\'':'''上文说“你需要将<code>rPublic</code>手动传给'''发送者'''”。但是在使用握手协议的系统中情况并非如此。例如,'''发送者'''会让'''接收者'''知道自己的存在,然后'''接收者'''会回复给'''发送者'''一个公钥(可能还有附加信息,例如密钥长度)。为简单起见,以下示例不涵盖握手协议的功能。 | ||
'''注\''\''\*:'''上文与下文的示例提到需要将密钥和信息序列化/解序列化。总体来说,在你将数据(尤其是二进制形式的)写入文件或通过网络传输前对其序列化是有益的。序列化能保证二进制数据“有结尾”,使你的脚本或shell读取时更加安全。 | '''注\''\''\*:'''上文与下文的示例提到需要将密钥和信息序列化/解序列化。总体来说,在你将数据(尤其是二进制形式的)写入文件或通过网络传输前对其序列化是有益的。序列化能保证二进制数据“有结尾”,使你的脚本或shell读取时更加安全。 | ||
若要发送加密数据: | 若要发送加密数据: <syntaxhighlight lang="lua"> | ||
local serialization = require("serialization") local component = require("component") | |||
--此表包含了要发送到接收方电脑的数据。 --表中还有信息头,供接收方用来解密数据。 local __packet = { | --此表包含了要发送到接收方电脑的数据。 --表中还有信息头,供接收方用来解密数据。 local __packet = { | ||
header = | |||
{ | { | ||
sPublic = nil, | sPublic = nil, | ||
iv = nil | iv = nil | ||
}, | }, | ||
data = nil | |||
} | } | ||
| Line 157: | Line 158: | ||
--数据被序列化并被加密了。 <span class="underline">packet.data = component.data.encrypt(serialization.serialize(</span>packet.data), encryptionKey, __packet.header.iv) | --数据被序列化并被加密了。 <span class="underline">packet.data = component.data.encrypt(serialization.serialize(</span>packet.data), encryptionKey, __packet.header.iv) | ||
--为简单起见,此样例中的电脑使用连接卡(ocdoc.cil.li/item:linked_card:zh) component.tunnel.send(serialization.serialize(__packet)) | --为简单起见,此样例中的电脑使用连接卡(ocdoc.cil.li/item:linked_card:zh) component.tunnel.send(serialization.serialize(__packet)) | ||
</syntaxhighlight> 若要接收加密数据: <syntaxhighlight lang="lua"> | |||
local serialization = require("serialization") local component = require("component") local event = require("event") | |||
--读取私钥。 local file = io.open("rPrivate","rb") | --读取私钥。 local file = io.open("rPrivate","rb") | ||
| Line 181: | Line 184: | ||
--解序列化解密后的数据。 local data = serialization.unserialize(data) | --解序列化解密后的数据。 local data = serialization.unserialize(data) | ||
--输出解密后的数据。 print(data) | --输出解密后的数据。 print(data) | ||
</syntaxhighlight> | |||
== 目录 == | == 目录 == | ||
{{:Component/contents/zh}} | {{:Component/contents/zh}} | ||
Latest revision as of 20:27, 24 August 2026
组件:数据卡
此组件由数据卡提供。
组件名:data。
1级回调函数
crc32(data:string):string
计算数据的CRC-32哈希值。结果为二进制格式。
decode64(data:string):string
对数据进行base64解码。
encode64(data:string):string
对数据进行base64编码。结果为二进制格式。
md5(data:string):string
计算数据的MD5哈希值。结果为二进制格式。
sha256(data:string):string
计算数据的SHA2-256哈希值。结果为二进制格式。
deflate(data:string):string
将数据用deflate算法压缩。
inflate(data:string):string
将数据用infalte算法解压。
getLimit():number
返回单次最大可传递给此扩展卡其他函数多少数据。
2级回调函数
encrypt(data:string, key:string, iv:string):string
使用给定密钥以及初始向量IV(最好为随机)对数据进行AES加密。
decrypt(data:string, key:string, iv:string):string
使用给定密钥以及初始向量IV对数据进行AES解密。
random(len:number):string
生成长度为 len 的随机二进制字符串。
3级回调函数
generateKeyPair([bitLen:number]):table, table
生成一对可用于多种加密算法的公钥与私钥。可选的第二个参数代表密钥长度,值可为256或384。 密钥类型包括"ec-public"和"ec-private"。密钥可以使用key.serialize():string来序列化。密钥中还包含一个函数key.isPublic():boolean。
ecdsa(data:string, key:userdata[, sig:string]):string or boolean
不给定签名则使用给定私钥生成数据的一份签名。若给定了签名则功能为使用公钥、先前生成的签名字符串以及原字符串校验签名。
ecdh(privateKey:userdata, publicKey:userdata):string
使用第一个参数给出的用户私钥与第二个参数给出的用户公钥,生成一个Diffie-Hellman共享密钥。密钥基本关系的示例为: ecdh(userA.private, userB.public) == ecdh(userB.private, userA.public)
deserializeKey(data:string, type:string):table
将密钥从字符串形式转化为其特有形式。
样例
此扩展卡可用于向其他在游戏中或在现实中的人发送加密数据。既然我们有能力创建密钥对和Diffie-Hellman共享密钥,那么我们就可以与这些人建立加密连接。
使用密钥对进行加密时,基本步骤为:
预备工作:
- (下列工作需要接收者完成)
- 生成一个公钥(
rPublic)与一个私钥(rPrivate)。
\\*若不能进行自动密钥交换,则你需要将rPublic手动传给发送者。
发送者必须:
\\\读取接收者的公钥(rPublic),将其解序列化并重构出密钥对象。
- 生成一个公钥(
sPublic)和一个私钥(sPrivate)。
\用rPublic和sPrivate生成加密密钥。
- 生成一个初始向量(IV)。
- 使用
sPublic.serialize()将sPublic转化为字符串
\\用serialization(序列化)库将数据序列化,然后使用加密密钥和IV将其加密。
- 序列化并发送信息,其中有明文形式的
sPublic与IV。
接收者必须:
- 读取发送者的私钥(
rPrivate),将其解序列化并重构出密钥对象。 - 接收信息,并使用serialization(序列化)运行库将其解序列化。然后使用
data.deserializeKey()解序列化sPublic。
\使用sPublic和rPrivate生成解密密钥。
- 使用解密密钥和IV来解密信息。
- 解序列化解密后的信息。
注\*:上文中使用了“加密密钥”和“解密密钥”两个术语。这两个密钥完全相同,因为这两个密钥都是使用ecdh()函数生成的。
注\\:上文说“你需要将rPublic手动传给发送者”。但是在使用握手协议的系统中情况并非如此。例如,发送者会让接收者知道自己的存在,然后接收者会回复给发送者一个公钥(可能还有附加信息,例如密钥长度)。为简单起见,以下示例不涵盖握手协议的功能。
注\\\*:上文与下文的示例提到需要将密钥和信息序列化/解序列化。总体来说,在你将数据(尤其是二进制形式的)写入文件或通过网络传输前对其序列化是有益的。序列化能保证二进制数据“有结尾”,使你的脚本或shell读取时更加安全。
若要发送加密数据:
local serialization = require("serialization") local component = require("component")
--此表包含了要发送到接收方电脑的数据。 --表中还有信息头,供接收方用来解密数据。 local __packet = {
header =
{
sPublic = nil,
iv = nil
},
data = nil
}
--读取公钥文件。 local file = io.open("rPublic","rb")
local rPublic = file:read("*a")
file:close()
--将公钥解序列化为二进制形式。 local rPublic = serialization.unserialize(rPublic)
--重建公钥对象。 local rPublic = component.data.deserializeKey(rPublic,"ec-public")
--为此会话生成一个公钥与一个私钥。 local sPublic, sPrivate = component.data.generateKeyPair(384)
--生成一个加密密钥。 local encryptionKey = component.data.md5(component.data.ecdh(sPrivate, rPublic))
--将信息头中值'iv'设定为一个随机生成的16位数字字符串。 __packet.header.iv = component.data.random(16)
--将信息头中值'sPublic'设定为一个字符串。 __packet.header.sPublic = sPublic.serialize()
--待加密的数据。 __packet.data = "lorem ipsum"
--数据被序列化并被加密了。 <span class="underline">packet.data = component.data.encrypt(serialization.serialize(</span>packet.data), encryptionKey, __packet.header.iv)
--为简单起见,此样例中的电脑使用连接卡(ocdoc.cil.li/item:linked_card:zh) component.tunnel.send(serialization.serialize(__packet))若要接收加密数据:
local serialization = require("serialization") local component = require("component") local event = require("event")
--读取私钥。 local file = io.open("rPrivate","rb")
local rPrivate = file:read("*a")
file:close()
--将私钥解序列化。 local rPrivate = serialization.unserialize(rPrivate)
--重建私钥对象。 local rPrivate = component.data.deserializeKey(rPrivate,"ec-private")
--使用event.pull()以接收来自发送者的信息。 local _, _, _, _, _, message = event.pull("modem_message")
--将信息解序列化。 local message = serialization.unserialize(message)
--从信息中获取公钥并解序列化。 local sPublic = component.data.deserializeKey(message.header.sPublic,"ec-public")
--生成解密密钥。 local decryptionKey = component.data.md5(component.data.ecdh(rPrivate, sPublic))
--使用解密密钥和IV来解密message.data中的加密数据 local data = component.data.decrypt(message.data, decryptionKey, message.header.iv)
--解序列化解密后的数据。 local data = serialization.unserialize(data)
--输出解密后的数据。 print(data)目录
| < 100% 15% 15% > | ||
| 组件API | 3D打印机 - 抽象总线 - 无线接入点 - 区块加载器 - 电脑 - 合成 - 数据卡 - 数据库 - 调试 - 无人机 - 驱动器 - EEPROM - 经验 - 文件系统 - 发电机 - 地质分析仪 - GPU - 全息投影仪 - 因特网 - 物品栏控制器 - 拴绳 - 微控制器 - 调制解调器 - 运动传感器 - 导航 - 网络拆分器 - 活塞 - 红石 - 运动红石机构 - 机器人 - 屏幕 - 告示牌 - 储罐控制器 - 牵引光束 - 转运器 - 隧道 - 世界传感器 | |
| ::: | 其它 | 访问组件 - 信号 |
| ::: | 模组联动 | 应用能源 |