毕业论文写作

毕业设计需求

免费毕设之基于Java的两个通用安全模块的设计与实现(源代码+论文)

目录

 

系统设计


1.1  功能模块流程图

为了方便系统方案的设计与功能的开发,在方案设计前,根据前面的需求分析,将系统的功能划分为口令部分功能模块和文件安全传输部分功能模块,这两个模块又各自细分为各个小模块,各小模块的功能流程图如下:

(一)     口令部分功能模块流程图

1.  登录模块流程图

在登录模块中根据需求分析设计了两种登录系统的口令模式,一个是默认口令模式,一个是一次性口令模式,当用户输入用户名及口令后,系统首先判断用户选的是默认口令类型还是一次性口令类型,如果是默认口令类型,则调用系统的默认口令处理方法将用户输入的口令经处理后,系统与数据库建立连接,连接不成功系统提示出错信息,如果连接成功,系统将口令处理后的结果跟数据库中口令表里的相应口令信息比较,经核对,口令信息一致则该用户可进入文件安全传输模块进行操作,否则提示出错信息,要求用户重新验证口令。登录模块流程图如图1所示。

1.  默认注册模块流程图

在默认注册模块中,用户输入用户名及口令。系统调用口令处理方法,接着连接数据库,连接成功则将口令信息与数据库里的记录比较,如无重复,则将口令及用户名写入数据库,并提示注册成功,如果写入数据库失败,则报失败提示。默认注册模块流程图如图2。

1.  一次性口令的注册模块流程图

在一次性口令注册模块中,用户输入用户名、口令长度、口令个数及口令。系统调用口令处理方法,接着连接数据库,连接成功则将口令信息与数据库里的记录比较,如无重复,则将最后生成的一个口令及用户名写入数据库,并显示用户要求的口令个数,失败,则报告失败提示。一次性口令的注册模块流程如图3。

(一)     文件安全传输部分功能模块流程图

1.  文件传输流程图

在文件传输模块中,用户首先选择一个要发送给服务器的文件。接着系统发送与服务器建立SSL连接的请求,成功后,系统调用文件加密方法给文件加密后,发送出去,发送成功失败都提示相应的消息。文件传输流程图如图6所示。

1.  服务器接收文件及处理流程图

在服务器接收文件及处理模块中,服务器响应客户端发来的SSL连接的请求,成功后,服务器选一个目录保存密文,接收完毕后,发送接收成功提示。服务器可以随时解密密文传输流程图如图7。

1.1  口令安全模块部分方案设计

根据口令部分功能模块流程图,口令模块的方案设计主要涉及到两种方式用于口令的认证及处理。

两种方式用于口令设计:

(1)基于单向函数

基于单向函数的方法是计算机存储口令的单向函数值而不是存储口令,当用户将口令传给计算机时,计算机使用单向函数计算,然后把单向函数的运算结果和它以前存储的单向函数值进行比较。由于计算机不再存储口令表,所以敌手侵入计算机偷取口令的威胁就减少了。

(2)基于SKEY原理

SKEY是进行口令认证方式之一,体现了一次性特性,它的实现过程如下:当用户输入初始口令pass,系统计算pass1=f(pass),pass2=f(pass1),……,pass(n+1)=f(passn)。其中n+1为用户要求生成的口令个数,系统将pass,pass1, pass2,……pass这些口令给用户保管,而将pass(n+1)存在数据库里该用户的名字后面,当用户第一次登录时,输入用户名和口令passn,系统计算f(passn),并把它和数据库里pass(n+1)比较,如果匹配,就证明该用户身份是真的。然后系统将passn 代替pass(n+1)。用户将passn作废,下次登录时用pass(n-1),以此类推。当用完后重新再获取。

以上这两种处理口令的过程中,消息摘要的生成是利用MD5算法求得。MD (Message Digest)消息摘要算法是一种单向散列函数,是当前最为普遍的哈希算法,MD5是第5个版本。对任意长的输入,MD5算法都将产生一个128位的输出。MD5算法是按512位进行处理的,首先它对输入的数据进行补位,使得数据位长度对512求余的结果是448。具体补位操作:先补一个1,然后补0直至满足上述要求,再用一个64位的数字表示数据的原始长度,这样数据就被填补成长度为512位的倍数。接着对数据依次按每次处理512位,每次进行4轮,每轮16步总共64步的数据变换处理,每次输出的结果为128位,然后把前一次的输出作为下一次数据变换的输入初始值,这样最后输出一个128位的杂凑结果。

1.2  文件安全传输部分方案设计

根据文件安全传输部分功能模块流程图,文件安全传输的方案设计主要涉及到在文件传输前用DES加密算法给要传输的文件加密得到一个加密后的密文,再将密文通过系统建立SSL协议文件安全传输的安全通道传给密文的接收端。在接收端密文接收成功后,接收端可以根据需要,将密文解密成明文,并自动保存在系统默认目录下。

1.2.1   DES加密算法

DES是一个分组加密算法,它将明文以64位为分组对数据加密。64位一组的明文从算法的一端输入,64位的密文从另一端输出。DES是个对称算法:加密和解密用的是同一算法(除密钥编排不同以外)。密钥通常表示为64位的数,但每个第8位都用作奇偶校验,因此密钥真正的长度是56位。整个算法是先经过初始置换IP的处理扰乱数据的原来顺序,然后进行16轮迭代运算,最后经过初始置换IP的逆置换IP-1得出64位的加密结果。整个算法如图8,其中一轮DES如图9所示。

1.1.1   SSL协议

1.  SSL协议概述

SSL协议(Secure Socket Layer,安全套接层协议)是基于对称密钥算法和公钥加密算法的加密传输信道的协议,位于应用层与传输层之间,独立于应用层协议,在SSL协议上可加载任何高层应用协议,应用程序可使用SSL应用接口为各类客户端/服务器产品提供安全传输服务,现已成为保密通信的标准。SSL协议采用RSA, DES等加密技术来实现数据的保密性,采用MD5信息摘要算法等来实现数据的完整性,使用数字证书进行身份认证。

2.  SSL协议体系结构

SSL协议是一个中间层协议,在OSI模型中,SSL介于传输层(如TCP/IP)和应用层之间,为应用程序提供了一条安全的网络传输通道,提供TCP/IP通信协议数据加密、版本号、会话密钥、数据压缩方法、数据完整性校验算法、客户端与服务器端身份验证等功能。它的主要目标是在两个通信应用之间提供私有性和可靠性。

3.  SSL协议的分层模型

SSL协议是一个分层的协议,共有两层组成。处于SSL协议底层的是SSL记录层协议(SSL Record Protocol,它位于可靠的传输层协议(如TCP/IP)之上,用于封装高层协议的数据。高层协议主要包括SSL握手协议(SSL HandshakeProtocol)、改变加密约定协议(Change Cipher Spec Protocol)、报警协议(AlertPT'OtOC01)等。

其中SSL握手协议允许服务方和客户方相互认证,并在应用层协议传送数据之前协商出一个加密算法和会话密钥,是SSL协议的核心。

SSL主要的工作流程包括:网络连接建立;与该连接相关的加密方式和压缩方式选择;双方的身份识别;本次传输密钥的确定;加密的数据传输;网络连接的关闭。

4.  应用数据的传输过程

(1)应用程序把应用数据提交给本地的SSL;

(2)发送端的SSL根据需要:

a)使用指定的压缩算法,压缩应用数据;

b)使用散列算法对压缩后的数据计算散列值;

c)把散列值和压缩数据一起用加密算法加密;

(3)密文通过网络传给对方;

(4)接收方的SSL

a)用相同的加密算法对密文解密,得到明文;

b)用相同的散列算法对明文中的应用数据散列;

c)计算得到的散列值与明文中的散列值比较;

(5)如果一致,则明文有效,接收方的SSL把明文解压后得到应用数据上交给应用层。否则就丢弃数据,并向发送方发出警告信息。严重的错误有可能引起再次的协商或连接中断。

1.2  数据库的设计

在SQL Server 2000数据库系统里利用企业管理器创建一个名为MyDB的数据库,并在这个数据库中设计一个表,表名为Person,这个表用于记录注册用户的用户名、口令信息、一次性口令的有效次数等相关信息,用户每次登录系统都要到此表进行身份验证。表的设计如表1所示:

Atribute

Type

ID

int

NAME

nchar

PASSWORD

nchar

RAND

nchar

TIMES

int

用户相关信息表

 

表Person的说明:

1)  ID用户编号,类型是整型;

2)  NAME是用户注册名;

3)  PASSWORD是主键,是口令经过处理后保存的口令处理结果;

4)  RAND是随机数,用于加密传输的文件内容的相关参数之一;

5)  TIMES是记录一次性口令用户登录的有效次数。

系统实现

1.1  与数据库建立连接

本系统是使用JDBC-ODBC桥驱动程序连接数据库的,JDBC-ODBC桥接器是用JdbcOdbc.Class和一个用于访问ODBC驱动程序的本地库实现的。首先建立ODBC数据源。ODBC数据源存储了如何与指定的数据建立程序的连接的有关信息。

先在WINDOWS ODBC数据源管理器中,建立一个名为“Person”的数据源的步骤如下:在“控制面板”里的“管理工具”中打开ODBC数据源管理器,选择“系统DSN”标签,单击“添加”按钮,选择数据源的驱动程序为SQL Server,输入数据源名称为“Person”,服务器选“本地”,用“使用网络登录ID的WINDOWS NT验证”,单击“下一步”,在“更改默认的数据库为”单选框,选择数据库为“MyDB”,单击“下一步”接受所有的默认选项。完成后,点“测试数据源”按钮,测试提示成功,则数据源配置成功。接着可以在程序中调用Class.forName方法加载JDBC-ODBC驱动程序,再调用DriverManager.getConnection方法发出连接请求。与数据库连接的部分代码如下:

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver" );

Stringurl="jdbc:odbc:Person";

Connection Insertconnection = DriverManager.getConnection(url);

1.2  口令认证及存储方式设计

本系统口令认证模块的默认口令实现的原理是基于单向函数,用MD5算出口令摘要,并保存在数据库里,以后每次登录都先将口令计算出摘要,与数据库里的摘要比较。

一次性口令实现原理及身份验证过程是基于SKEY原理,每次计算的方法是当用户第一次注册时,用MD5计算出口令的消息摘要,并从中截取用户要求的口令长度的字符串,作为一个口令生成,如果用户口要求的口令生成的个数大于1,则将这个生成的口令再用MD5计算出口令的消息摘要,并从中截取用户要求的口令长度的字符串,依此类推,计算出用户要求的个数,并将最后一个生成的口令存于数据库中,当用户用这些口令进行身份验证时就与SKEY的认证过程一样。

1.3  数字证书创建

在DOS下使用J2SDK提供的keytool工具创建密钥库,密钥库名为mykeystore,添加一个名为mytest的证书,mykeystore密钥库为服务器的密钥库。将mytest证书导出到clienttrust密钥库中。clienttrust密钥库为客户端信任的密钥库。

1.4  关键代码说明

1.  口令生成及处理模块

此模块使用的频率比较多,在用户登录、注册、口令更改功能中都要反复用到,因此将此模块功能封装在接口ProductKey中,方便其它程序的调用。在接口里定义了两个同名的方法DigestKey(Stringstr)和DigestKey(String str,int a,int b),由MyProductKey类具体实现它的方法,其中str表示要进行处理的口令字符串,a表示用户口令的长度, b表示用户输入口令的个数,前一个方法用于默认口令处理返回一个些口令的摘要,后一个方法用于一次性口令处理,返回一系列一次性口令。

DigestKey(String str)是将用户输入的口令生成消息摘要,一次性口令的处理方法DigestKey(String str,int a,int b)是将用户初始输入的口令生成消息摘要,然后截取消息摘要字符串的前三个字符,后三个字符,接着根据用户要求的口令长度a,再从消息摘要字符串中第14位开始截取a-6个字符,将这三次取得的字符串连接一起得到一个一次性口令。然后将这个口令按上面方法再产生一次性口令。依此循环,循环b次最后得到b个口令。最终生成用户要求数量的口令及口令长度。

此模块生成消息摘要的部分代码如下:

MessageDigestm=MessageDigest.getInstance("MD5");

m.update(x.getBytes("UTF8"));

byte s[ ]=m.digest( );

MessageDigest类提供了计算消息摘要的方法,首先生成m的对像,执行update()方法将原始数据传递给该对象,然后执行digest()方法得到消息摘要。

一次性口令处理方法部分代码如下:

public String[] DigestKey(Stringstr,int a,int b){

           ……

           for(int j=0; j<num; j++){

MessageDigestm=MessageDigest.getInstance("MD5");

              m.update(x.getBytes("UTF8"));

               byte s[]=m.digest( );

               Stringresult="";

               for (inti=0; i<s.length; i++){

                     result+=Integer.toHexString(s[i]);

                      }

                fir =result.substring(0, 3);

                sec =result.substring(29, 32);

                tir =result.substring(14, 14+len);

                c=fir.concat(sec);

                v=c.concat(tir);

                p[j]=v;

                x=p[j];

         }

           return p;

         }

此代码中num为参数b传递给num的口令个数。fir,sec,tir为三次截取的字符串,再由concat()函数将这三个字符串连接成一个一次性字符串口令,保存在p数组中。再将刚生成的口令字符串传递给x字符串,进行下一个口令的生成。如此循环num次,生成num个口令,最后由数组p返回所有生成的一次性口令。

2.  文件内容加解密处理模块

此模块主要用来完成发送文件的加密和接收密文的解密,加密跟解密是基于口令加密的,即由口令生成密钥。这部分功能在客户端发送文件及服务器端解密文件都要使用,因此将此功能也封装在接口Enc_Dec,在Enc_Dec中定义了加密方法Encrypt(String passw,byte[] rand,byte[] text)和解密方法Decrypt(String passw,byte[] rand,byte[] ctext),它们的第一个参数是口令,第二个参数是随机数,第三个参数是加解密的内容。由类MyEnc_Dec具体实现它的方法,这样方便调用,又简化程序。

此模块中完成加密的部分代码如下:

char[] passwd=password.toCharArray( )

PBEKeySpec pbks=new PBEKeySpec(passwd)

SecretKeyFactory kf=

             SecretKeyFactory.getInstance("PBEWithMD5AndDES")

SecretKey k=kf.generateSecret(pbks)

Ciphercp=Cipher.getInstance("PBEWithMD5AndDES")

PBEParameterSpec ps=newPBEParameterSpec(salt,1000);      

                    cp.init(Cipher.ENCRYPT_MODE, k, ps)

byte ctext[]=cp.doFinal(buff)

类PBEKeySpec用于保存口令,它的构造器传入的参数是字符数组,所以用了字符串的toCharArray( )方法生成字符数组。SecretKeyFactory类的generateSecret()方法用于生成密钥。PBEParameterSpec类用于指定基于口令加密的的参数,它的构造器的第一个参数为随机数(盐),第二个参数为进行迭代计算的次数。通过Cipher工厂类的getInstance()方法指定加密算法或解密算法所用的算法名字,init()方法对Cipher对象初始化,它的第一个参数指定密码器准备进行加密还是解密第二个参数则是传入加密或解密所使用的密钥。最后执行doFinal(),完成加密。解密方法类似于加密方法,只是在init()方法对Cipher对象初始化时第一个参数指定密码器准备进行解密操作。

3.  保存密/明文处理模块

此模块主要用来完成保存密文和明文的。由于加密明文中用到了随机数和口令,要解密这样的密文必须要用相同的随机数和口令,因此密文的前两个字节写入口令占的字节数,接着写入八个字节的随机数,再写入口令,最后将密文写入。当要解密文件时根据密文前面的口令长度即可得到口令跟随机数和密文起始内容。进而调用解密方法解密。将这个模块封装在saveEnc_Decfile接口中,由MysaveEnc_Decfile类具体实现它的方法,有利于简化程序,方便调用

4.  用户登录模块

1)   系统实现功能介绍

此模块主要完成用户的口令验证登录,由LoginFrame.java文件里的代码实现,运行后的界面有用户名输入框、密码框、密码类型选择框及“确定”、“取消”、“改口令”、“注册”四个按钮组成,其中单击各按钮进入相应的界面。

在此界面上口令验证的操作流程及程序处理如下:

输入:用户名和密码,选择口令类型。

处理:

l 校验字符的有效性。检验用户是否满足输入的要求,即检验用户名和口令文本框是否为空,若为空,则提示用户输入用户名和口令。

l 根据口令类型,选择相应的口令处理方法来处理口令,得到一个值。

l 根据用户名和口令处理后的值到数据库中验证身份是否符合。

l 如果身份验证成功,系统根据口令的类型判断数据库中的口令信息是否替换。如果口令是默认型的则不用替换,如果是一次性口令类型的,则将此次登录的口令替换数据库中的口令信息,并重新写入有效次数。

l 关闭本窗体,进入文件发送界面。

输出:登录失败信息。

2)   此部分实现的关键类及方法说明

LoginFrame.java文件中类LoginFrame中的成员函数logindispose()用于接收并校验登录口令的字符,然后引用包中接口ProductKey,根据其成员变量choiceIndex来判断口令类型,调用相应的接口ProductKey中的方法来处理口令,如果choiceIndex值为0则用默认口令处理方法DigestKey()来处理口令,返回一个处理后的消息摘要字符串数组,并将之到数据库里验证。如果choiceIndex值为1,则调用处理一次性口令的DigestKey()方法,但是设b的值为1,只生成1个口令并将之到数据库里验证。成员变量choiceIndex的值如果是1,则将登录的口令(没经过处理)替换数据库里的口令信息以及更改有效次数。

替换数据库里的口令及有效次数代码如下:

loginupdatequery= "Update Person set PASSWORD ='"+logpass+"',TIMES="+times+"Where NAME = '"+logname+ "'and   PASSWORD='"+insertpass+"'";

5.  默认口令注册窗口设置

1)   系统实现功能介绍

这部分主要完成用户的口令注册功能,由RegisterFrame.java文件里的代码实现,运行后的界面有用户名输入框、密码输入框、确认密码输入框及“确定”、“返回”两个按钮组成,其中单击各按钮进入相应的界面。

在此界面上注册默认口令的操作流程及程序处理如下:

输入:用户名、密码、确认密码。

处理:

l 校验字符的有效性。检查用户名是否满足输入的要求,即检查用户名和密码文本框是否为空,若为空,则提示用户输入用户名和密码。

l 检验用户输入的口令与确认口令是否一致,如果一致则进行相应的口令处理。

l 执行插入过程。

l 返回登录框。

输出:注册成功或失败信息。

2)   此部分实现的关键类及方法说明

RegisterFrame.java文件中类RegisterFrame中的成员函数RegInfoInput()用于接收并校验注册信息的字符,然后引用包中的接口ProductKey中的成员函数DigestKey()默认口令处理方法来处理口令,生成此口令的一个消息摘要,然后连接数据库,执行插入数据库。

6.  一次性口令注册窗口设置

1)   系统实现功能介绍

这部分主要完成用户的一次性口令注册功能,由RegisterFrame1.java文件里的代码实现,运行后的界面有用户名输入框、密码输入框、确认密码输入框、口令长度、口令个数及“确定”、“返回”两个按钮,其中单击各按钮进入相应的界面。

在此界面上注册一次性口令的操作流程及程序处理如下:

输入:用户名、密码、确认密码。

处理:

l 校验字符的有效性。检查用户输入的注册信息是否满足输入的要求,即检查用户名、口令文本框、口令长度、口令个数等是否为空,若为空,则提示用户输入。

l 检验用户输入的口令与确认口令是否一致,如果一致则进行相应的口令处理。

l 执行插入过程。

l 打开口令生成对话框。

l 返回登录框。

输出:注册成功或失败信息。

2)   此部分实现的关键类及方法说明

RegisterFrame1.java文件中的类RegisterFrame1中的成员函数RegInfoInput()用于接收并校验注册用户输入的注册信息,然后引用包中的接口ProductKey,调用接口中的一次性口令处理方法DigestKey()来处理注册用户输入的初始口令,生成用户要求个数和长度的一系列相关联的口令,然后将最后一个生成的口令执行插入数据库。用类keyDialog向用户显示并保存生成的其它口令。

7.  默认口令更改窗口设置

这部分主要完成默认型口令的更改,由ChangeFrame.java文件里的代码实现,用户需要提供用户名,原口令、新口令、确认口令。系统先确定用户的合法性,如果合法,则进行口令更改处理。实现方法类似于前面的默认口令身份认证和注册。

8.  一次性口令更改窗口的设计

这部分主要完成一次性类型口令的更改,由ChangeFrame.java文件里的代码实现,用户需要提供用户名,原口令、新口令、确认口令、口令长度、口令个数。原口令是用户在前一次生成的一次性口令中没有失效的口令。系统先确定用户的合法性,如果合法,则进行口令更改处理。实现方法类似于前面的一次性口令身份认证和注册。

9.  文件传输窗口设置

1)   系统实现功能介绍

这部分主要完文件的选择、文件的加密、与服务器建立连接和秘密文件传输,由Myselectfile.java和MySSLClientFile.java文件里的代码实现,运行后的界面有文件名框、打开文件选择对话框按钮、确定按钮、返回按纽。其中确定按钮用于发送文件。

在此界面上文件传输的操作流程及处理如下:

输入:文件名。

处理:

l 校验字符的有效性。检查用户各输入是否满足输入的要求,即检查文件选择文本框是否为空,若为空,则提示用户选择文件。

l 客户端与服务器建立连接,并验证服务器是否可信

l 验证成功后建立秘密通道,加密文件并将口令跟随机数一起通过秘密通道发给接收端。

l 返回登录框。

输出:文件发送成功或失败信息。

2)   此部分实现的关键类及方法说明

Myselectfile.java文件中的类Myselectfile中的成员函数OpenFile()用于打开文件选择框,SentFile()用于显示文件传输成功失败的信息。而在文件MySSLClientFile.java中类MySSLClientFile通过System类的静态方法setProperty()设置系统参数javax.net.ssl.trustStore,指定客户端信任的证书,通过SSLSocketFactory类型创建Socket对像,并用创建的对象的createSocket()方法和服务器指定的端口建立连接。通过getOutputStream()方法得到输出流,通过该输出流发送的信息将加密后传给服务器程序。由Random类生成随机数,并将口令与随机数一起传递给类MyEnc_Dec实现接口Enc_Dec中的Encrypt()方法用于加密文件内容。

此部分与接收端建立连接及指定密钥库代码如下:

System.setProperty("javax.net.ssl.trustStore","clienttrust");

SSLSocketFactory ssf=

         (SSLSocketFactory)

SSLSocketFactory.getDefault( );

                      s =ssf.createSocket("127.0.0.1", 5432);

10.      服务器接收窗口设置

1)   系统实现功能介绍

这部分主要完成密文的接收、保存、解密相应的密文、并将解密后的文本显示在文本框中并保存在一个默认的目录中,由MySSLServerRule.java文件和Myserverfile.java文件里的代码实现。运行后的界面有两个文件名框、“打开文件选择对话框”按钮、“保存文件选择对话框”按钮、明文显示文本框。其中接收密文区里的“文件选择对话框”按钮用于保存接收的文件,明文区里的按钮用于打开密文执行解密。

在此界面上密文接收并解密、明文显示、保存明文的操作流程及程序处理如下:

输入:文件名。

处理:

l 服务器监听客户机是否有连接请求。

l 服务器发证书给客户端证明自己的身份,身份认证成功后建立文件传输的安全通道。

l 接收客户端发来的密文。

l 解密指定的密文,并显示在明文文本框中,同时保存明文到默认的目录。

输出:密文保存成功或失败信息。

2)   此部分实现的关键类及方法说明

MySSLServerRule.java文件中类MySSLServerRule中通过System类的静态方法setProperty ()设置两个系统参数。方法中的第一个参数是系统参数的名称,javax.net.ssl.keyStore指定密钥库的名称;第二个参数是为系统参数设置的值,javax.net.ssl.keyStorePassword指定密钥库的密码。通过SSLServerSocketFactory类型的对像创建ServerSocket对像。Accept()方法用等待客户程序连接,ServerSocket的getInputStream( )方法可以得到输入流,通过该输入流读取客户端发送来的信息并自动解密。类MysaveEnc_Decfile实现密文、明文的保存。类MyEnc_Dec实现接口中Enc_Dec的Decrypt()方法用来解密密文。

此部分与发送端建立连接及指定密钥库代码如下:

System.setProperty("javax.net.ssl.keyStore","mykeystore");

System.setProperty("javax.net.ssl.keyStorePassword","wshr.ut");

SSLServerSocketFactory ssf=

                          (SSLServerSocketFactory)

       SSLServerSocketFactory.getDefault();

ServerSocket ss=ssf.createServerSocket(5432);

 

源文件


最新毕业设计成品

版权所有© 帮我毕业网 并保留所有权利

QQ 1370405256 微信 biyebang

QQ:629001810微信:biyebang

收缩