RSA密钥生成原理以及工具rsaeuro的移植和编译-程序员宅基地

技术标签: 密码  RSA  公钥  嵌入式系统  人工智能  加密  

rsaeuro是一款小巧的开源rsa算法库,它支持生成RSA Key,签名,校验,对称加密,哈希算法等多种功能,可以说是一款应对非对称加解密应用的利器,被广泛应用在多种嵌入式应用场合,比如前东家的高安机顶盒,下面简述一下它的开发步骤。

获取代码

代码从github获取

https://github.com/mort666/RSAEuro

修改编译错误

由于代码比较古老,有些规范和语法新平台下的编译器汇编器已经不在支持了,并且开源代码本身的构建系统也有一些问题,所以下载下来的代码不能直接编译,需要修改,总的修改文件有如下几个:

修改补丁如下:

diff --git a/install/unix/makefile b/install/unix/makefile
old mode 100644
new mode 100755
index 6aee6c3..4ca599c
--- a/install/unix/makefile
+++ b/install/unix/makefile
@@ -35,15 +35,15 @@ CPUT = 386
 ANSISTD = 
 
 # utility routines
-del = del
-COPY = copy
+del = rm -fr
+COPY = cp
 
 # name of main executable to build
 PROG = all
 
 # Normal C flags.
 ifdef CPUT
-CFLAGS = $(INCL) -O -c -DPROTOTYPES=0 -DUSEASM=1 -DDES386=1
+CFLAGS = $(INCL) -O -c -DPROTOTYPES=0 -DDES386=1
 else
 ifdef ANSISTD
 CFLAGS = $(INCL) -O -c -DPROTOTYPES=0 -DUSA_ANSI=1
@@ -56,13 +56,13 @@ ASMFL = $(INCL) -c -Wa,-L
 MFLAGS = -I. -I$(RSAEURODIR)
 
 # The location of the common source directory.
-RSAEURODIR = ../source/
+RSAEURODIR = ../../source/
 RSAEUROLIB = rsaeuro.a
 RSAREFLIB = rsaref.a
 
 # The location of the demo source directory.
 RDEMODIR = ../rdemo/
-DEMODIR = ../demo/
+DEMODIR = ../../demo/
 
 ifdef CPUT
 all : rstdasm.$(O) demo $(RSAREFLIB)
diff --git a/source/des386.s b/source/des386.s
index 4607040..d69c03a 100644
--- a/source/des386.s
+++ b/source/des386.s
@@ -27,6 +27,7 @@
 		0.91 Current revision some minor bug fixes to original
 		code.  Comments revised to reflect original C code.
 */
+    .code32
 
 	/* Crafty DES Function */
 #define	F(l,r,key) 	movl r,%eax ;\
@@ -35,34 +36,34 @@
 	andl $0xfcfcfcfc,%eax ;\
 \
 	movb %al,%bl ;\
-	xorl _Spbox+6*256(%ebx),l ;\
+	xorl Spbox+6*256(%ebx),l ;\
 	movb %ah,%bl ;\
 	rorl $16,%eax ;\
-	xorl _Spbox+4*256(%ebx),l ;\
+	xorl Spbox+4*256(%ebx),l ;\
 	movb %al,%bl ;\
-	xorl _Spbox+2*256(%ebx),l ;\
+	xorl Spbox+2*256(%ebx),l ;\
 	movb %ah,%bl ;\
-	xorl _Spbox(%ebx),l ;\
+	xorl Spbox(%ebx),l ;\
 \
 	movl 4+key(%esi),%eax ;\
 	xorl r,%eax ;\
 	andl $0xfcfcfcfc,%eax ;\
 \
 	movb %al,%bl ;\
-	xorl _Spbox+7*256(%ebx),l ;\
+	xorl Spbox+7*256(%ebx),l ;\
 	movb %ah,%bl ;\
 	rorl $16,%eax ;\
-	xorl _Spbox+5*256(%ebx),l ;\
+	xorl Spbox+5*256(%ebx),l ;\
 	movb %al,%bl ;\
-	xorl _Spbox+3*256(%ebx),l ;\
+	xorl Spbox+3*256(%ebx),l ;\
 	movb %ah,%bl ;\
-	xorl _Spbox+256(%ebx),l
+	xorl Spbox+256(%ebx),l
 
 
 	.align 2
-.globl _desfunc
+.globl desfunc
 
-_desfunc:
+desfunc:
 	pushl %ebp
 	movl %esp,%ebp
 	pushl %esi
diff --git a/source/rsa386.s b/source/rsa386.s
index 9ce6e6f..6817be1 100644
--- a/source/rsa386.s
+++ b/source/rsa386.s
@@ -37,6 +37,7 @@
 
 	.align 2
 	.globl _NN_Cmp
+	.code32
 
 _NN_Cmp:
 	pushl %ebp

编译

在RSAEuro-master/install/unix目录下,直接执行make命令,完成编译:

编译后生成redemo, mdemo,randemo几个可执行程序,可以进行RSA 密钥生成,签名和校验。

以redemo为例,执行后的输出列表如下,可以选择创建密钥,加载密钥,给文件签名等等功能。

默认rsaeuro支持的keylength为508-1024, 也就是支持最大的素数乘积为1024位,以当前的计算机处理速度而言,仅仅相当于128长度密码AES的加密强度,所以一般应用中使用的是2048位的RSA算法,rsaeuro也可以支持到,方法是做如下改动:

这样修改后的redemo,将可以产生2048位的RSA公钥和私钥.

密码中的映射

如果用数学上映射的视角观察加密算法,你会发现加密算法的本质是一个映射,更准确地说是一个单射。只要知道任何一方,都能够反求另一方。只是求解的难度可能会有差异。

两个质数相乘,就算得到的结果再大你也不会觉得困难,但是如果让你对一个较大的数进行质因数分解,求出原本的质数组合,就没那么容易了。单射关系成立,得出结果很简单,但分解回两个质数很难,即便根据素数定理,这种分解一定存在并且唯一,这是分解质因数的特性,许多密码的设置正是运用了这个特性(NP难问题)。

2010年发布的研究报告指出,300台电脑在3年时间内不停运转,通过分解质因数得到的数是232位数。

RSA密码系统加密举例

根据百度描述的算法步骤,我们生成一组RSA KEY,并实现加解密

RSA密钥的生成过程

step 1:

寻找两个大素数p和q. 实际生活中,每台性能一般的普通电脑都可以在几分钟之内通过对奇整数的随机选择获取到满足要求的素数。实际上这个概率可以根据素数定理得到,并不是很低,完全可以做到。

step 2:

计算出p*q的欧拉φ函数, 令N=p*q, r=φ(N)=φ(p*q). 欧拉φ函数是乘性函数,所以可以得到r的值:

       r=φ(n)=φ(p*q)=φ(p)*φ(q)=(p-1)(q-1)

step 3:

随即选择一个整数e,满足e < r,并且e,r互素,也就是(e,r)=1. 这样,得到了公钥(N,e).

step 4:

这一步,还需要在找一个数,它是e关于r的模逆元,记为d, 满足ed-1=kr, k为整数。也就是ed与1模r同余:

        ed\equiv 1(mod \ r)

所以前面第三步才要求e,r互素,否则不可能存在模逆元d. (N,d)就是私钥。

step 5:

销毁p,q,发布公钥,自己保留私钥。

销毁p,q的原因是:d是根据e和r算出来的,而r=φ(n)=φ(p*q)=φ(p)*φ(q)=(p-1)(q-1), 所以仅仅根据公钥(n,e)推算d的话,需要对n进行素数分解为pxq,根据素数定理,分解唯一,且大素数分解非常困难,实践中很难做到,所以需要销毁p,q.

一个例子

选择素数p=5,q=11,则n=55, r=φ(n)=φ(55)=φ(5*11)=φ(5)*φ(11)=4*10=40. 选择e=3,并且gcd(40,3)=1.

为了得到d,根据e*d≡1 mod φ(n), 也就是3*d mod 40=1, 3d=k*40+1.编程获取:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i = 1; 
    while(i)
    {
	if((i * 40+1)%3==0) {
		printf("%s line %d, avail d is %d, k is %d.\n",
			__func__, __LINE__, (i * 40+1)/3, i);
	}
	i ++;
    }
    return 0;
}

满足要求的d有多个,这个很自然,如果d0满足要求,则d0+k*φ(n)(dn≡d0(mod φ(n)) 自然也满足要求,也就是说,如果一个模φ(n)的同余类的某个元素是解,则此同余类的所有元素都是解,但是因为(e,r)=1,所以虽然这样的同余类有φ(n)-1个,但是满足要求的同余类只有1个。

e*d0≡1 mod φ(n) φ(n)≡0 mod φ(n) 

<=>

 e*d0≡1 mod φ(n) , ekφ(n)≡0 mod φ(n)

<=> 

e(d0 + kφ(n))≡1 mod φ(n), k为整数:

所以,d0可以看做是特解,而通解是d0关于模r的同余类, 从下面程序的输出也可以看到27,67,107...都可以表示成27 + k * 40的表示形式。

并且,由于(d,r)=1,这说明,满足要求的小于r的数字中,d只有一个.

我们选择最小的一个,当k取2时,d=27,得到私钥(n,d)=(55,27).

所以:公钥(n,e)=(55,3),私钥(n,d)=(55,27).

假设需要加密的明文信息为m=14:

加密过程:得到密文c=m^e mod 55=14^3 mod 55=49

解密过程:得到明文m=c^d mod 55=49^27 mod 55=14

NOTE:每次加密的消息m需要满足m<N,如果消息太长,就截成几段。

验证

用普通的计算器很难验证计算结果,原因是没有任何一个计算器能够处理49^27这么大的数字,即便p,q我们已经选择的足够小了。

GNU提供了一个开源工具BC,能够处理任意精度的数值计算,它支持以任意精度给出结果,很多的胶水语言,比如perl, html,python等做计算器应用的时候实际上是调用了bc的算法, man bc如下图所示:

比如我想得到根号2的2000位,那就在控制台输入如下指令即可得到结果:

$ echo "scale=2000;sqrt(2)"|bc

计算49^27也不在话下,校验过程如下,通过BC,我们验证了利用上面产生的RSA密钥对14进行加密和解密的正确性,如下图所示:

前面提到,私钥的d有多个,如果d可以取27,那么d也就可以取27 + k * 40的任意值,我们取67验证一下:

公钥(n,e)=(55,3),私钥(n,d)=(55,67).

假设需要加密的明文信息为m=14:

加密过程:得到密文c=m^e mod 55=14^3 mod 55=49

解密过程:得到明文m=c^d mod 55=49^67 mod 55=14

同样是对的.

这个结论可以证明:

如果:

c^d\equiv m(\ mod \ n)

c^{d+kr}\equiv m ( \ mod \ n)

证明过程:

c^{d+kr}\equiv m ( \ mod \ n)\Leftrightarrow c^d\cdot c^{kr}\equiv m ( \ mod \ n)

由于 r=φ(n), n是素数,所以n必定和c互素,根据费马-欧拉定理:

c^{r}\equiv 1 ( \ mod \ n),\ r = \varphi (n)

所以:

c^{kr}\equiv 1^k ( \ mod \ n)\equiv 1 ( \ mod \ n),\ r = \varphi (n)

所以

c^d\cdot c^{kr}\equiv 1\cdot m ( \ mod \ n)

所以:

c^{d+kr}\equiv m ( \ mod \ n)

得证

关于中间证明用到的费马-欧拉定理和费马小定理,详见吗咪叔的证明:

另一个例子

假定加密模数是素数43和59的乘积,这样可以得到n=43*59=2537为模,取e=13.并且满足(e, φ(n)) = (13, 42*58) = 1.

下一步必须找到私钥,就必须找到e=13关于模φ(2537)=φ(43*59)=42*58=2436的逆。利用欧拉算法进行计算,可得d=937是13模2436的逆。

e*d≡1 mod φ(n) = 1 mod 2436,也可以用程序得到d:

#include <stdio.h>
#include <stdlib.h>
using namespace std;

typedef long long LL;
void ex_gcd(LL a, LL b, LL &x, LL &y, LL &d)
{
	if (!b)
		d = a, x = 1, y = 0;
	else
		ex_gcd(b, a % b, y, x, d), y -= x * (a / b);
}

LL gcd(LL a, LL b)
{
	return !b ? a : gcd(b, a % b);
}

void remainder_equation(int a, int b, int n)
{
	long long X, Y, d, r;
	long long res;
	long long min_res;

	d = gcd(a, n);
	ex_gcd(a, n, X, Y, d);
	if (b % d == 0) {
		r = n / d;
		X = X * (b / d) % n;//特解
		for (int i = 0 ; i < d; i++) {
			res = (X + (i * r)) % n;//通解
			printf("%lld\n", res);            //输出所有解
		}
		min_res = (X % (n / d) + (n / d)) % (n / d);
		printf("min_res %lld.\n", min_res); //输出最小解
	} else {
		printf("No Sulutions!\n");
	}
}

int main(void)
{
	int a = 13;
	int b = 1;
	int n = 2436;

	remainder_equation(13, 1, 2436);
	return 0;
}

待加密数字为:"i love you",按照在26个字母表中的下标表示:09 12 15 22 05 25 15 21。

由于需要满足待加密数字m<n.所以,将加密信息拆分为:0912  1522 0525 1521 四组。

分别加密:

c1=m^e mod n = (0912)^13 mod 2537 = 875.

c2=m^e mod n = (1522)^13 mod 2537 = 99.

c3=m^e mod n = (0525)^13 mod 2537 = 402.

c4=m^e mod n = (1521)^13 mod 2537 = 1325.

所以,密文为:0875 0099 0404 1325

解密:

m1=m^d mod n = (875)^937 mod 2537 = 912.

m2=m^d mod n = (99)^937 mod 2537 = 1522.

m3=m^d mod n = (402)^937 mod 2537 = 525.

m4=m^d mod n = (1325)^937 mod 2537 = 1521.

所以,机密后的明文为:

0912 1522 0525 1521.

完全吻合,证明利用公钥进行加密和解密的过程是完全正确的。

bc验算:

模同余类的图形化表示,geogebra floor/ceil函数:

国密公钥算法

国钥公钥密码算法SM2也是一种非对称加密算法,应用场景和领域和RSA相当,但是存储密度和安全性更强一些,由于是国密算法,主要部署在内销电子产品芯片中。

对于高次的同余方程,如果x0是方程的一个解,则x≡ x0(mod m)剩余类也是方程的解,如下程序所示:

#include <stdio.h>

// x^5+x+1 ≡ 0(mod 7)
int main(void)
{
	int i;

	for(i = 0 ; i < 7; i ++)
	{
		if((i*i*i*i*i + i + 1)%7 == 0){
			printf("%s line %d, %d is result.\n", __func__, __LINE__, i);
		}
	}
	/*
	*main line 11, 2 is result. x≡ 2(mod 7)
	*main line 11, 4 is result. x≡ 4(mod 7)
	*/
	return 0;
}

素性判断的多项式算法

2002年,素数判定问题的多项式时间算法被找到,此前人们一直不知道该问题的确切难度,这一伟大发现改变了2000多年来人们对素数判定方法难度的认知,这个伟大发现是3位印度数学家完成的,现在这个高效的素数判定方法被称为AKS算法,由3位作者姓氏的首字母组成,实现代码如下:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
//AKS algorithm for testing if a number is prime
typedef unsigned long long uint64;
 
uint64 gcd(uint64 n, uint64 r) 
{
	return r == 0 ? n : gcd(r, n % r);
}
 
bool check_power(uint64 n)
{
	for (double i = 2; i <= ceil(log(n) / log(2)); i++)
	{
		double p = pow(n, 1.0 / i);
		if (p - floor(p) == 0)
			return true;
	}
	return false;
}
bool test(uint64 r)
{
	uint64 i = 2;
	while (i <= sqrt(r)) {
		if (i % r == 0)
			return false;
		i++;
	}
	return true;
}
 
uint64 syz(uint64 r) {
	uint64 i = 2;
	while (i <= sqrt(r)) {
		if (i % r != 0)
			i++;
		else 
			r /= i;
		return r;
	}
}
uint64 pf(uint64 a, uint64 b, uint64 r) {
	uint64 z = 1;
	while (b != 0)
	{
		if (b % 2 == 0)
		{
			b >>= 1;
			a = (a * a) % r;
		}
		else
		{
			b --;
			z = (z * a) % r;
		}
	}
	return z;
}
 
uint64 mods(uint64 n, uint64 r, uint64 a)
{
	int x = 5;//
	uint64 f = 1, g = x * a, y = n, h; 
	while (y != 0)
	{
		if (y % 2 == 0)
		{
			y >>= 1;
			h = g * g;
			g = h % (uint64)(pow(x, r) - 1);
		}
		else
		{
			y --;
			h = f * g;
			f = h % (uint64)(pow(x, r) - 1);
		}
	}
	return f;
}

int main(void)
{
	uint64 a = 1;
	int x = 5;
	uint64 n; 
	printf("please input integer n:"); 
	scanf("%llu", &n);
	if (n < 2)
	{
		printf("n should be greater or equals to 2\n");
		return 0;
	}
	if (check_power(n))
	{
		printf("%llu is a composite number!\n", n);
		return 0;
	}
	else
	{
		uint64 r = 2;
		while (r < n)
		{
			if (gcd(n, r) != 1)
			{
				printf("%llu is a composite number\n", n);
				return 0;
			}
			else if (test(r))
			{
				uint64 q = syz(r - 1);
				if (q >= 4 * sqrt(r) * (uint64)(log(n) / log(2)) && pf(n, (r - 1) / q, r) != 1)
					break;
			}
			r ++;
		}
		for (a = 1; a <= 2 * sqrt(r) * ((uint64)(log(n) / log(2))); a++)
		{
			if (mods(n, r, a) != (((uint64)pow(x, n) - a) % ((uint64)pow(x, r) - 1)))
			{
				printf("%llu is a prime number\n", n);
				return 0;
			}
		}
		printf("%llu is a composite number\n", n);
	}
	return 0;
}

参考文档

每日一课:奥数知识点 —— 同余法

bc 命令,Linux bc 命令详解:算术操作精密运算工具 - Linux 命令搜索引擎


结束

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/tugouxp/article/details/124890631

智能推荐

用OCC+VS+Qt创建并显示一个几何_occ opengldriver-程序员宅基地

文章浏览阅读1.7k次,点赞2次,收藏25次。用OCC+VS+Qt创建并显示一个几何_occ opengldriver

Unity学习心得_unity课程总结心得-程序员宅基地

文章浏览阅读4.2k次,点赞2次,收藏12次。Unity学习心得第一个项目 Roll A Ball1.基本模型和场景操作双击Cube,表示聚焦(在Scene场景中)或者按下 F键Persp:透视视图 (会产生近大远小) ISO:平行视野(不会产生近大远小的效果)2.世界坐标系和局部坐标系:世界坐标:以世界原点为中心的坐标 局部坐标:以父节点的中心_unity课程总结心得

maven的下载与安装教程(超详细)_maven安装-程序员宅基地

文章浏览阅读10w+次,点赞432次,收藏1.1k次。前言本篇文章是基于win10系统下载安装Maven的教程。一、 Maven介绍1. 什么是Maven​ Maven是一个跨平台的项目管理工具。作为Apache组织的一个颇为成功的开源项目,其主要服务于基于Java平台的项目创建,依赖管理和项目信息管理。maven是Apache的顶级项目,解释为“专家,内行”,它是一个项目管理的工具,maven自身是纯java开发的,可以使用maven对java项目进行构建、依赖管理。2. Maven的作用依赖管理依赖指的就是是 我们项目中需要使用的第三方_maven安装

研究生如何读文献 写论文 发文章 毕业论文_研究生一天读多少文献-程序员宅基地

文章浏览阅读2.1k次,点赞3次,收藏13次。研究生论文写作步骤1. 先看综述,后看论著。看综述搞清概念,看论著掌握方法。2. 早动手在师兄师姐离开之前学会关键技术。3. 多数文章看摘要,少数文章看全文。掌握了一点查全文的技巧,往往会以搞到全文为乐,以至于没有时间看文章的内容,更不屑于看摘要。真正有用的全文并不多,过分追求全文是浪费,不可走极端。当然只看摘要也是不对的。4. 集中时间看文献,看过总会遗忘。看文献的时间越分散_研究生一天读多少文献

微光app电脑版_智米电暖器智能版1S体验:全面领跑AIoT、将智能生活进行到底-程序员宅基地

文章浏览阅读547次。【科技犬体验】2019年10月15日,智米正式推出了旗下电暖器新品——智米电暖器1S和智米电暖器智能版1S对于没有集中供暖的长江中下游地区居民而言,电暖器是不折不扣的"保命神器"。而在深秋的北方,昼夜温差较大,这种时候使用灵活、易于搬运的电暖器也成为更加明智的选择。在北方每年的冬季,室内温度就直接关系着大家在家的舒适度,而对于室内温度不达标的用户,购买电暖器就成为几乎唯一的选择。科技犬已经入手智米..._智米电暖器智能版app

《Hadoop与大数据挖掘》——2.6 TF-IDF算法原理及Hadoop MapReduce实现-程序员宅基地

文章浏览阅读312次。本节书摘来自华章计算机《Hadoop与大数据挖掘》一书中的第2章,第2.6节,作者 张良均 樊哲 位文超 刘名军 许国杰 周龙 焦正升,更多章节内容可以访问云栖社区“华章计算机”公众号查看。2.6 TF-IDF算法原理及Hadoop MapReduce实现2.6.1 TF-IDF算法原理原理:在一份给定的文件里,词频(Term Frequency,..._hadoop mapreduce如何实现实现tf-idf

随便推点

GSM劫持+短信嗅探 “半夜盗刷”-程序员宅基地

文章浏览阅读5.1k次,点赞2次,收藏21次。【PConline资讯】“一觉醒来,手机里多了上百条验证码,而账户被刷光还背上了贷款”——近期犯罪分子利用“GSM劫持+短信嗅探”的方式盗刷网友账户的事件成为网络热点。那么,该如何防范这种短信嗅探犯罪呢?安全专家指出,最简单的一招就是睡觉前关机,手机关机后就没有了信号,短信嗅探设备就无法获取到你的手机号。在主流App中,许多账户登录及资金操作都可以通过手机号码加短信验证码的方式实现,对于用...

Docker删除容器命令_docker delete-程序员宅基地

文章浏览阅读2.6w次,点赞4次,收藏25次。删除容器 之前要先docker stop 容器1. 删除指定容器docker rm -f <containerid>12. 删除未启动成功的容器docker rm $(docker ps -a|grep Created|awk '{print $1}')或者docker rm $(docker ps -qf status=created)1233. 删除退出状态的容器docker rm $(docker ps -a|grep Exited|awk '{print $1}_docker delete

乌龙(一)ntp对时_ntp对时 时区-程序员宅基地

文章浏览阅读107次。emmm…今天新搭了一套虚拟机(安装时一步过了 啥也没配置),操作时发现系统时间一直不对,于是安装了ntp跟阿里云等时钟源对过,发现一对时系统就变成了昨天,我把系统时间强制改为了现在,再次对时,时间又回退到昨天,最后发现时区选错了,选成了PST。解决方法cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime..._ntp对时 时区

数据结构_实验三_二叉树的基本操作_二叉树叶子节点实验-程序员宅基地

文章浏览阅读6.3k次,点赞18次,收藏81次。1.需求分析1.1 输入数据建立二叉树,分别以前序、中序、后序的遍历方式显示输出二叉树的遍历结果。输入输出形式:124$$5$3$$preOrder1 2 4 5 3inOrder4 2 5 1 3afterOrder4 5 2 3 1功能:利用树存储数据,采用递归的方式做到先序、中序、后序三种遍历方式输出数据范围:0~9测试数据:    124$$5$3$$      ..._二叉树叶子节点实验

P5738 【深基7.例4】歌唱比赛-程序员宅基地

文章浏览阅读311次。题目描述n(n\le 100)n(n≤100)名同学参加歌唱比赛,并接受m(m\le 20)m(m≤20)名评委的评分,评分范围是 0 到 10 分。这名同学的得分就是这些评委给分中去掉一个最高分,去掉一个最低分,剩下m-2m−2个评分的平均数。请问得分最高的同学分数是多少?评分保留 2 位小数。输入格式无输出格式无输入输出样例输入 ..._【深基7.例4】歌唱比赛

Vue简明实用教程(04)——事件处理_vue html里面如何直接写事件函数-程序员宅基地

文章浏览阅读1.1k次,点赞4次,收藏5次。在Vue中可非常便利地进行事件处理,例如:点击事件、鼠标悬停事件等。_vue html里面如何直接写事件函数