第10课 交易安全性如何保证? -- scriptSig/scriptPubKey/Script Engine

在前面第8课 账号相关概念:公钥/私钥/Public Key Hash/P2PKH我们讲公/私钥的时候,说过:A给B转账的时候,会先用A的私钥进行签名,再转账给B的公钥。

这个过程,说明了2件事:用A的私钥签名,证明了这笔钱是A的;转账给B的公钥,证明了这笔钱是转给B的,不是转给别人的。

接下来,B要花这笔钱,比如转给C;同样的,要用B的私钥签名,转账给C的公钥。

下面就来详细的分析一下1个Transaction的内部结构,看看究竟都是如何用私钥签名的,又是如何转账给公钥的。

交易的详细结构

下图是用的比特币的命令行工具getrawtransaction来详细展示了1个Transaction ID为028cfae228f8a4b0caee9c566bd41aed36bcd237cdc0eb18f0331d1e87111743的交易的

内部结构:

该交易有3个输入(vin里面),2个输出(vout)。

我们会看到,每1个vin里面,都有1个txid字段,1个vout字段,这2个字段合在一起也就组成了我们上节课所说的UTXO。1个UTXO = 1个Transaction Id + output Index。

scriptSig字段就是我们所说的,私钥的签名。

每1个vout,有1个字段value,字段n,字段scriptPubKey。

value就是转账给对方的钱数,n是output里面的编号(也就是下1次花费这个UTXO时,对应的vin里面的字段vout)。

scriptPubKey就是我们所说的,对方的公钥。

scriptSig详细解释

scriptSig里面有asm和hex2个字段,都是什么意思呢?

上面的vin里面,第1个输入,这2个字段的值,分别为:

“asm” : “3044022055bac1856ecbc377dd5e869b1a84ed1d5228c987b098c095030c12431a4d524902

2055523130a9d0af5fc27828aba43b464ecb1991172ba2a509b5fbd6cac97ff3af01

048aefd78bba80e2d1686225b755dacea890c9ca1be10ec98173d7d5f2fefbbf881a6e918f3b05

1f8aaaa3fcc18bbf65097ce8d30d5a7e5ef8d1005eaafd4b3fbe”,

“hex” : “473044022055bac1856ecbc377dd5e869b1a84ed1d5228c987b098c

095030c12431a4d5249022055523130a9d0af5fc27828aba43b464ecb1991172

ba2a509b5fbd6cac97ff3af0141048aefd78bba80e2d1686225b755dacea890c9ca1be10ec

98173d7d5f2fefbbf881a6e918f3b051f8aaaa3fcc18bbf65097ce8d30d5a7e5

ef8d1005eaafd4b3fbe”

细心的读者会发现,这2个字段的值其实是一样的,只是hex在开头插入了字符47,中间插入了一个字符41,其他部分完全一样。

asm为assembly(拼装,或者汇编的意思),hex为其16进制的表达。

所以呢,这里的asm和hex就是同1个东西,里面包含了2部分:

signature(付款人的私钥的签名) + pub key(付款人的公钥),以41这个字符隔开。

scriptPubKey详细解释

scriptPubKey里面有asm, hex, reqSigs(暂时忽略), type, address几个字段。

同样,asm和hex当中同1个意思,只是不同的编码格式;

type: 也就是前面我们说的P2PKH,Pay to Public Key hash;

address: 也就是对方的收款地址,或者说钱包地址。

第1个vout的scriptPubKey的值如下:

OP_DUP OP_HASH160 634228c26cf40a02a05db93f2f98b768a8e0e61b

OP_EQUALVERIFY OP_CHECKSIG

address值为:

“1A3q9pDtR4h8wpvyb8SVpiNPpT8ZNbHY8h”

这2者是什么关系呢? scriptPubKey的格式,看起来很奇怪,OP_DUP, OP_HASH160,都是啥???

这就是接下来要讲的script Engine.

Script Engine

单纯的看scriptPubKey是看不懂的,我们需要把scriptPubKey和下1个,要花费它的交易的scriptSig,拼接在一起来看。

scriptPubKey代表的是收款人的公钥信息;下1个要花费这个UTXO的交易里面的vin,必然有该公钥对应的私钥的前面信息,也就是scriptSig。

2部分拼接在一起,scriptSig在前,scriptPubKey在后(注意:scriptPubKey是当前交易的,scriptSig是下1个交易的,要花费这个UTXO的),就长这个样子:

OP_DUP OP_HASH160 634228c26cf40a02a05db93f2f98b768a8e0e61b

OP_EQUALVERIFY OP_CHECKSIG

其中,signature, pub key 这2部分的内容,就类似上面的vin里面的asm部分,因为字符串太长了,此处就省略了,用 代替。

上面这串东西,就是1个script,1个简单的DSL语言(关于什么是DSL,自己百度之)。

这串script,被丢进Script Engine里面执行,执行结果就是TRUE/FALSE,表示这个人有没有资格花这笔钱,或者说这笔交易是否有效。

Script Engine是一个基于栈的脚本解释器,下面就来详细解释一下这串脚本是如何执行的:

从左往右,扫描上面这个Script(也就是一个拼接的字符串),中间用空格隔开的,共7部分(7个子串)。

遇到字符串,则入栈; 遇到OP_打头的,要么是1元操作符,栈顶1个元素出栈,计算,结果再入栈;要么是2元操作符,栈顶的2个元素出栈,计算,结果再入栈。

下面看一下入栈/出栈的详细过程:

//第1个字符串,签名,入栈

//第2个字符串,pub key,入栈

OP_DUP //第3个字符串:1元操作符,DUP就是拷贝的意思。也就是把栈顶元素拷贝1份,入栈。现在栈顶元素是pub key , 也就是把pub key拷贝1份,入栈。

OP_HASH160 //第4个字符串:1元操作符,对栈顶元素,做HASH160运算。也就是对pub key做HASH160运算,再入栈

634228c26cf40a02a05db93f2f98b768a8e0e61b

//第5个字符串:其实就是pub key hash,入栈

OP_EQUALVERIFY

//第6个字符串:2元操作符,校验栈顶的2个元素是否相等。此时栈顶的2元素,

//1个是刚入栈的pub key hash, 一个是经过前面的Hash160计算出来的pub key hash。

//2者不等,整个就结束了,返回FALSE;

//2者相等,全部出栈,此时栈里还剩2个元素:signature, pub key

OP_CHECKSIG

//第7个字符串:操作符,检测栈顶的2个元素,pub key和signature是否能对应的上。对应的上,说明这个签名的私钥,和收款人的公钥可以对上。有资格花这笔钱。

总结

每1个节点上面都有这样1个Script Engine,对于接收到的每1笔交易的每个vin,都会把其scriptSig和引用的UTXO(也就是上1个交易的输出)的scriptPubKey拼接起来,形成1个字符串,塞入Script Engine,得到结果是True/False。

如果是False,说明该笔交易的付款人,没有资格花这笔钱,该笔交易不合法,会被直接丢弃。

这个过程,也就是我们在第4课里挖矿的环节里面所讲的,交易的验证过程。

相关链接:

《第9课 Transaction数据结构、UTXO、钱包 – 详解》
《第8课 账号相关概念:公钥/私钥/Public Key Hash/P2PKH》

有兴趣朋友也可以进一步关注公众号“架构之道与术”, 获取原文。
或扫描如下二维码:
这里写图片描述

<think>好的,用户现在问的是关于`aa-exec -p /usr/bin/mbient/dialog-engine --`的解释。我需要先回顾之前的对话历史,了解用户的需求背景。之前用户询问的是如何测试AppArmor配置,特别是关于D-Bus接收规则的验证,其中用到了这个`aa-exec`命令。现在用户希望深入理解这个命令的作用参数。 首先,我需要明确`aa-exec`是什么。从之前的回答中,我知道这是AppArmor的一个工具,用于在特定配置下运行程序。用户可能在使用这个命令时遇到了问题,或者想确认其正确用法,尤其是在测试配置时。 接下来,用户提供的命令是`aa-exec -p /usr/bin/mbient/dialog-engine --`,后面的`--`通常用于分隔命令参数要执行的命令。这里的关键部分是`-p`参数,指定了AppArmor的配置文件路径。用户可能想知道这个参数的具体含义,以及整个命令的结构。 然后,我需要解释每个部分的作用。比如,`-p`参数后面跟的是profile的名称或路径,这里指向`/usr/bin/mbient/dialog-engine`,也就是之前配置的AppArmor规则文件。`--`之后的部分是要执行的命令,例如之前的例子中用的是`dbus-send`命令来发送D-Bus消息。 用户可能不太清楚为什么需要用`aa-exec`来运行程序,而不是直接执行。这时候需要解释AppArmor的工作原理,即通过配置profile来限制进程的行为,而`aa-exec`的作用就是确保进程在指定的profile下运行,从而应用相应的安全策略。 另外,用户可能对参数的正确使用有疑问,比如是否必须使用`--`,或者`-p`参数是否支持其他格式。这时候需要说明`--`的作用是防止参数解析歧义,确保后面的命令不会被误认为是`aa-exec`的参数。 还可能存在一些常见的错误,比如profile路径不正确,或者没有正确加载配置,导致`aa-exec`无法应用策略。这时候需要提醒用户检查`aa-status`来确认profile是否已加载,或者查看日志来排查问题。 最后,结合用户之前的问题,他们可能是在测试AppArmor规则时使用这个命令,所以需要强调在测试中正确使用`aa-exec`的重要性,以确保测试结果准确,即只有指定profile的进程才能通过规则,而其他进程被拒绝。 总结下来,我需要分步骤解释`aa-exec`的作用、参数含义、使用场景,并结合之前的配置示例,说明如何正确使用这个命令来验证AppArmor规则是否生效。同时,还要指出常见的问题解决方法,帮助用户更好地理解应用这个工具。</think>以下是对 `aa-exec -p /usr/bin/mbient/dialog-engine --` 的详细解释: --- ### **命令作用** `aa-exec` 是 AppArmor 提供的工具,用于在 **指定 AppArmor 配置策略(profile)的约束下** 运行一个进程。 `-p /usr/bin/mbient/dialog-engine` 表示强制将后续启动的进程限制在 `/usr/bin/mbient/dialog-engine` 这一配置策略中。 --- ### **参数解析** 1. **`-p /usr/bin/mbient/dialog-engine`** - `-p`:指定要应用的 AppArmor profile(配置文件)路径。 - `/usr/bin/mbient/dialog-engine`:AppArmor 配置文件的路径,通常位于 `/etc/apparmor.d/` 目录下,文件名与进程路径一致。 - 该参数确保后续命令在 `/usr/bin/mbient/dialog-engine` 的规则限制下运行。 2. **`--`** - 符号 `--` 表示后续内容为 **要执行的命令及其参数**,防止命令参数与 `aa-exec` 的参数混淆。 --- ### **典型使用场景** #### **验证 AppArmor 规则** 在测试 D-Bus 接收规则时,需确保发送进程的标签与配置中的 `peer=(label=...)` 匹配。例如: ```bash sudo aa-exec -p /usr/bin/mbient/dialog-engine -- \ dbus-send --system \ --dest=com.daimler.Speech1 \ /com/daimler/Speech1/Engine/Controller \ com.daimler.Speech1.Engine.Controller.PlayPrompt \ string:"test_prompt" ``` - **关键逻辑**:强制 `dbus-send` 在 `/usr/bin/mbient/dialog-engine` 的配置策略下运行,使 AppArmor 将其识别为授权进程。 --- ### **底层机制** 1. **进程标签绑定** - AppArmor 通过进程的 **安全上下文(security context)** 识别其所属配置策略。 - `aa-exec` 会修改子进程的上下文,使其继承指定 profile 的规则。 2. **策略匹配验证** - 当进程尝试访问资源(如发送 D-Bus 消息)时,AppArmor 会检查其标签是否与规则中的 `peer=(label=...)` 匹配。 - 匹配成功则放行,否则记录拒绝日志(见 `/var/log/syslog`)。 --- ### **常见问题** #### **1. 配置文件未加载** - **现象**:`aa-exec` 报错 `Profile /usr/bin/mbient/dialog-engine not found`。 - **解决**:使用 `sudo apparmor_parser -r /etc/apparmor.d/usr.bin.mbient.dialog-engine` 重新加载配置。 #### **2. 命令执行权限不足** - **现象**:普通用户运行时提示权限错误。 - **解决**:需通过 `sudo` 调用 `aa-exec`(如示例中的 `sudo aa-exec ...`)。 --- ### **验证命令是否生效** #### **1. 检查进程标签** ```bash ps -eo pid,label,args | grep "dbus-send" ``` 输出应包含 `/usr/bin/mbient/dialog-engine` 标签: ``` PID LABEL COMMAND 1234 /usr/bin/mbient/dialog-engine dbus-send --system ... ``` #### **2. 查看 AppArmor 日志** ```bash sudo grep -i 'apparmor=.*ALLOWED' /var/log/syslog ``` 若规则生效,会显示类似记录: ``` apparmor="ALLOWED" operation="dbus_send" profile="/usr/bin/mbient/dialog-engine" name="com.daimler.Speech1" ``` --- ### **与其他工具对比** | 工具 | 用途 | 区别 | |------|------|------| | `aa-exec` | 临时为进程绑定配置策略 | 需手动指定 profile | | `aa-enforce` | 全局启用配置策略 | 影响所有匹配进程 | | `aa-complain` | 将配置策略设为“仅记录”模式 | 不实际拦截行为 | --- 通过 `aa-exec` 可精准控制单次进程的执行策略,是验证复杂 AppArmor 规则的必备工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值