信息安全2
更新时间:2023-11-09 03:06:01 阅读量: 教育文库 文档下载
一、实习目的
1.理解对称加密算法的原理,熟悉常用的对称加密算法:DES、
TripleDES、Blowfish;
2.以DES加密算法为例,掌握分组加密算法加、解密过程的实现。 二、实习要求
1.实习前认真预习第5章有关内容;
2.熟悉java中的java.security.*和java.crypto.*中的相关类; 3.按要求认真撰写实习报告。 三、实习内容
1.[阶梯任务]
(1) 以本地两个目录模拟两个用户,实现基本DES加密通讯,引入的包具体到类;
(2)对于DES加密实现图形界面,用户可以输入明文和密钥,在文本框中显示对应密文;
(3)实现用户对文件的操作,用户可以通过指定路径文件和密钥,加密结果存储在指定文件中;
(4)采用SSL,建立安全通信过程; (5)将方案移植到某个web应用中。
2.[实现提示]
(1) 可以利用java中的KeyGenerator类创建对称秘钥,利用工厂类
KeyGenerator的静态方法getInstance()获得KeyGenerator()类对象;
(2) 方法getInstance()的参数为字符串类型,指定加密算法的名称如:
Blowfish、DES、DESede、HmacMD5或HmacSHA1等;
(3) 利用工厂类Cipher的对象可以创建密码器。同样的,getInstance()
的参数为字符串类型,指定加密算法的名称。
四、实验结果
1、实现客户端和服务器连接模拟两个用户,实现基本DES加密通讯。
2、加密产生密文结果:
3、服务器接收并解密得到明文:
4、输出加密文件内容乱码,很遗憾没有修改正确。 五、实验总结
1、DES加密算法:DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准,是1972年美国IBM公司研制的对称密码体制加密算法。其密钥长度为56位,明文按64位进行分组,将分组后的明文组和56位的密钥按位替代或交换的方法形成密文组的加密方法。
2、DES加密算法特点:分组比较短、密钥太短、密码生命周期短、运算速度较慢。
3、DES工作的基本原理:入口参数有三个:key、data、mode。 key为加密解密使用的密钥,data为加密解密的数据,mode为其工作模式。当模式为加密模式时,明文按照64位进行分组,形成明文组,key用于对数据加密,当模式为解密模式时,key用于对数据解密。实际运用中,密钥只用到了64位中的56位,这样才具有高的安全性。
4、SSL协议:普通的TCP通信无法保证数据的安全,它随时可能被第三方截获而泄漏通信双方之间的隐私,SSL协议能够保证交互双方的数据按密文方式传输,第三方在没有私钥的情况下几乎无法破解,从而到达保密的目的。
5、SSL的交互过程: ?
建立TCP连接
由于SSL协议依赖于TCP连接实施,所以在SSL交互之前需要先建立TCP连接。客户端connect
服务端,服务端acccept客户端,经历三次握手以后TCP连接建立。
?
客户端发送SSL请求
客户端(Client)向服务端(Server)发送自身使用的SSL版本、加密算法的相关配置、随机数据以及其在在SSL协议中需要用到的信息。
?
服务端处理SSL请求
服务器(Server)反馈给客户端(Client)自己的SSL版本、加密算法的相关配置、随机数据以及用自己的私有密钥加密的SERVER-HELLO信息。服务端(Server)紧接着将自己的证书(包含公共密钥)传递过去。同时有个可选项目,即服务端(Server)可以要求客服端(Client)发送自己的证书。
?
客户端验证服务端身份
客服端(Client)用服务端(Server)传递过来证书验证服务端(Server)的身份,证书验证通过后利用服务端(Server)的公共密钥尝试解开被其用私有密钥加密过的SERVER-HELLO信息,如果解开失败,说明该SERVER-HELLO必然是假的,故结束本次通信。 ?
客户端发送公共密钥加密过的随机数据
客户端端(Client)生成随机数据(sharedsecret),并且把这个随机数据用服务端(Server)发送过来的的公共密钥加密,此次加密过程产生本次握手中的premastersecret(这个步骤是有可能有服务端的参与的,具体情况由他们使用的加密算法决定),然后将它(premastersecret)送回给服务端(Server)。如果服务端(Server)要求需要验证客户端(Client),那么客服端(Client)也需要自己把自己的证书(包含公共密钥)传递过去,同时送一些自己签过名(私有密钥加密)的数据过去。 ?
服务端用私有密钥解密加密后的随机数据并协商暗号
Server验证完client的身份之后,然后用自己的私有密钥解密得到premastersecret然后双方利用这个premastersecret来共同协商,得到mastersecret(可理解为premastersecret为双方协商的暗号,然后使用这个暗号再协商一个mastersecret用来产生真正的会话密钥用来传输数据)以此来保证数据的决对安全。 ?
服务端跟客户端利用暗号生成加密算法跟密钥key
双方用mastersecret一起产生真正的sessionkey,这将是一个对称加密的key。这个key还可以用来验证数据完整性。双方再交换结束信息。握手结束。
接下来双方就可以用协商好的算法和密钥key,采用对称加密算法来通信了。
6、算法说明:
利用java中的KeyGenerator类创建对称秘钥,利用工厂类KeyGenerator的静态方法getInstance()获得KeyGenerator()类对象; 方法getInstance()的参数为字符串类型,指定加密算法的名称如:Blowfish、DES、DESede、HmacMD5或HmacSHA1等;利用工厂类Cipher的对象可以创建密码器。同样的,getInstance()的参数为字符串类型,指定加密算法的名称。
六、附录—代码 Ceaser.java
import java.util.Scanner; public class Ceaser {
private String mingwen;//明文 private char[] plain;
private String miwen = \;//密文 private int Key;//密钥
private int n = 5;//字母表起始编码
public Ceaser(String mingwen, int Key) { }
public String miwen() {
int m = plain.length; char Str;
for(int i = 0; i < m; i++) {
Str = plain[i];
if(Str >= 32 && Str <=126) { }
if(Str < 32) {
Str += 95;
Str = (char)((Str + Key - n)? + n);
this.mingwen = mingwen; int m = mingwen.length(); plain = new char[m]; for(int i = 0; i < m; i++) { }
if(Math.abs(Key) > 95) { }
this.Key = Key;
Key = Key?;
plain[i] = mingwen.charAt(i);
}
}
}
}
if(Str > 126) { }
miwen += Str;
Str -= 95;
return miwen;
class Deciphering {
private String miwen;
private int n = 5;//字母表起始编码 private int Key;
public Deciphering(String miwen, int key) { }
public String decipherProcess() {
int l = miwen.length(); char []encrypt = new char[l]; char Str;
String mingwen = \; for(int i = 0; i < l; i++) { }
for(int i = 0; i < l; i++) {
Str = encrypt[i];
if(Str >= 32 && Str <=126) {
encrypt[i] = miwen.charAt(i); this.miwen = miwen; if(Math.abs(key) > 95) { }
this.Key = key;
key = key?;
}
}
}
}
Str = (char)((Str - Key - n)? + n);
if(Str < 32) { }
if(Str > 126) { }
mingwen += Str;
Str -= 95; Str += 95;
return mingwen;
Servers.java
import java.awt.EventQueue;
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File;
import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; //import java.net.*; import java.util.Random; import javax.swing.*; public class Servers { /**
* @param args */
private ServerSocket server = null; private Socket socket = null;
private ServerSocket server1 = null; private Socket socket1 = null; private DataOutputStream out = null; private DataInputStream in = null; private DataOutputStream out1 = null; private DataInputStream in1 = null;
private JFrame frame1;
private JTextArea mingwenkuang; /**
* @wbp.parser.entryPoint */
public Servers() {
} /**
* Launch the application. */
public static void main(String[] args) { } /**
* Create the application. */ /**
* Initialize the contents of the frame1. */
private void initialize() {
frame1 = new JFrame();
frame1.setTitle(\frame1.setBounds(100, 100, 500, 420);
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame1.getContentPane().setLayout(null);
//对话框
mingwenkuang = new JTextArea();
mingwenkuang.setBounds(56, 176, 390, 162); mingwenkuang.setLineWrap(true);
frame1.getContentPane().add(mingwenkuang); mingwenkuang.setColumns(10);
EventQueue.invokeLater(new Runnable() {
public void run() { }
try { }
Servers window = new Servers(); window.frame1.setVisible(true); e.printStackTrace();
initialize();
} catch (Exception e) {
});
JButton connect = new
JButton(\
connect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
socket = new Socket(); socket1 = new Socket(); try{
server = new ServerSocket(4331); server1 = new ServerSocket(4332); }catch(Exception e) {
System.out.println(\正在监听\ } try {
System.out.println(\等待客户端呼叫\ socket = server.accept(); socket1 = server1.accept();
客
户
端
地
址
:
System.out.println(\
\
}
sendmingwen
in1
}catch(Exception e) {
in = new DataInputStream(socket.getInputStream());
=
new
DataInputStream(socket1.getInputStream());
System.out.println(\正在等待客户端呼叫\ }
}); JButton
=
new
JButton(\
sendmingwen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
byte[] inputByte = null; int length = 0;
FileOutputStream fos = null; String filePath = \try { try {
fos = new FileOutputStream(new File(filePath)); inputByte = new byte[1024];
//System.out.println(\开始接收数据...\
} );
}
}
while }
((length = in.read(inputByte, 0,
inputByte.length)) > 0) {
fos.write(inputByte, 0, length); fos.flush();
} finally{
if (out != null)
out.close(); fos.close(); socket.close(); if (fos != null) if (socket != null)
}}catch (IOException e1) {
// TODO Auto-generated catch block e1.printStackTrace();
JButton sendmiyao = new
JButton(\
sendmiyao.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
byte[] inputByte = null; int length = 0;
FileOutputStream fos = null; String filePath = \try { try {
fos = new FileOutputStream(new File(filePath)); inputByte = new byte[1024];
//System.out.println(\开始接收数据...\while ((length = in.read(inputByte, }
if (out != null)
fos.write(inputByte, 0, length); fos.flush();
0,
inputByte.length)) > 0) {
} finally{
out.close(); fos.close(); socket.close();
if (fos != null) if (socket != null)
}}catch (IOException e) {
// TODO Auto-generated catch block e.printStackTrace();
}
}
}); JButton
jiemi
=
JButton(\
jiemi.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { SDec sdec = new SDec(); String mingwen = sdec.Des(); mingwenkuang.setText(mingwen);
}
});
//connect.setBounds(150, 350, 100, 35); connect.setBounds(140, 19, 119, 35); sendmingwen.setBounds(294, 19, 108, 35); sendmiyao.setBounds(142, 72, 115, 35); jiemi.setBounds(297, 70, 107, 35); /*send.setBounds(400, 380, 90, 35); * frame1.getContentPane().add(send); * */
frame1.getContentPane().add(jiemi); frame1.getContentPane().add(connect); frame1.getContentPane().add(sendmingwen); frame1.getContentPane().add(sendmiyao); JLabel
lblNewLabel
=
JLabel(\
lblNewLabel.setBounds(19, 146, 75, 15); frame1.getContentPane().add(lblNewLabel);
}
new
new
}
Clinet.java
import java.awt.EventQueue;
import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File;
import java.io.FileInputStream; import java.io.IOException; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.Socket; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.JTextPane; import javax.swing.JLabel;
public class Client {
JFrame frmGf;
private JTextArea mingwenkuang; private Socket socket = null;
private Socket socket1 = null; private DataInputStream in = null; private DataOutputStream out = null; private DataInputStream in1 = null; private DataOutputStream out1 = null;
/**
* Launch the application. */
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() { }
try { }
Client window = new Client(); window.frmGf.setVisible(true); e.printStackTrace();
} catch (Exception e) {
}
});
/**
* Create the application. * @wbp.parser.entryPoint */
public Client() { } /**
* Initialize the contents of the frame. */
private void initialize() {
socket = new Socket(); socket1 = new Socket(); frmGf = new JFrame();
frmGf.setTitle(\frmGf.setBounds(100, 100, 500, 420);
frmGf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frmGf.getContentPane().setLayout(null);
//对话框
mingwenkuang = new JTextArea();
mingwenkuang.setBounds(82, 182, 352, 134); mingwenkuang.setLineWrap(true);
frmGf.getContentPane().add(mingwenkuang); mingwenkuang.setColumns(10);
JButton connect = new JButton(\、连接服务器\connect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub try {
InetAddress InetSocketAddress InetSocketAddress
address socketaddress1 socketaddress2
= =
= new new
initialize();
InetAddress.getByName(\InetSocketAddress(address, 4331); InetSocketAddress(address, 4332);
socket.connect(socketaddress1); socket1.connect(socketaddress2);
in = new DataInputStream(socket.getInputStream());
} );
}
out = new DataOutputStream(socket.getOutputStream());
in1 = new DataInputStream(socket1.getInputStream()); out1
=
new
DataOutputStream(socket1.getOutputStream());
} catch (Exception e) { }
// TODO Auto-generated catch block e.printStackTrace();
JButton jiami = new JButton(\jiami.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { }
sendmingwen
=
new
// TODO Auto-generated method stub String mingwen = mingwenkuang.getText(); if(mingwen == null || mingwen.equals(\{ }
Skey_DES sk = new Skey_DES(); sk.Key();
SEnc senc = new SEnc(mingwen); String miwen = senc.Ees();
mingwenkuang.setText(\请输入明文\return ;
}); JButton
JButton(\
sendmingwen.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int length = 0; double sumL = 0 ;
byte[] sendBytes = null; FileInputStream fis = null; boolean bool = false; try { try {
File file = new File(\要传输的文件路径 long l = file.length(); //socket = new Socket();
//socket.connect(new InetSocketAddress(\48123));
//out
=
DataOutputStream(socket.getOutputStream());
fis = new FileInputStream(file); sendBytes = new byte[1024]; while ((length
=
fis.read(sendBytes,
sendBytes.length)) > 0) {
sumL += length;
//System.out.println(\已
传
输
\ out.write(sendBytes, 0, length);
out.flush();
}
if(sumL==l){ bool = true; }
} finally{
if (out != null) out.close(); if (fis != null) fis.close(); if (socket != null)
socket.close(); }}catch (IOException e1) {
// TODO Auto-generated catch block e1.printStackTrace();
}
}
} ); JButton
sendmiyao
=
JButton(\
sendmiyao.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub int length = 0; double sumL = 0 ;
byte[] sendBytes = null;
new
0,
:
new
FileInputStream fis = null; boolean bool = false; try{ try { File file = new File(\要传输的文件路径 long l = file.length(); //socket = new Socket();
//socket.connect(new InetSocketAddress(\48123));
//out
=
DataOutputStream(socket.getOutputStream());
fis = new FileInputStream(file); sendBytes = new byte[1024]; while ((length
=
fis.read(sendBytes,
sendBytes.length)) > 0) {
sumL += length;
//System.out.println(\已
传
输
\ out1.write(sendBytes, 0, length);
out1.flush();
}
if(sumL==l){ bool = true; }
} finally{
if (out != null) out.close(); if (fis != null) fis.close(); if (socket != null)
socket.close(); }}catch (IOException e) {
// TODO Auto-generated catch block e.printStackTrace();
}
}
});
connect.setBounds(121, 17, 114, 35); jiami.setBounds(294, 20, 106, 35); sendmingwen.setBounds(127, 91, 112, 35); sendmiyao.setBounds(294, 87, 113, 35); /*send.setBounds(400, 380, 90, 35); * frame.getContentPane().add(send);
* */
new
0,
:
}
}
frmGf.getContentPane().add(connect); frmGf.getContentPane().add(jiami); frmGf.getContentPane().add(sendmingwen); frmGf.getContentPane().add(sendmiyao); JLabel
label
=
new
JLabel(\
label.setBounds(21, 146, 104, 27); frmGf.getContentPane().add(label);
SDec.java
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.ObjectInputStream;
import java.security.InvalidKeyException; import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException; import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException;
//基于DES的解密算法 //使用对称秘钥解密
public class SDec {
public String Des(){
String p = null; try {
//从文件读入密文
FileInputStream fs = new FileInputStream(\); int num = fs.available(); byte[] ctext = new byte[num]; fs.read(ctext);
//从文件读入秘钥
FileInputStream fs2=new FileInputStream(\); ObjectInputStream os=new ObjectInputStream(fs2);
public SDec(){
// TODO 自动生成的构造函数存根 }
}
}
Key key=(Key)os.readObject();
Cipher cp = Cipher.getInstance(\); cp.init(Cipher.DECRYPT_MODE, key); byte[] ptext = cp.doFinal(ctext);//解密 p = new String(ptext, \);
System.out.println(p);//明文输出 } catch (FileNotFoundException e) { }
return p;
e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); } catch (IOException e) {
} catch (NoSuchAlgorithmException e) { } catch (NoSuchPaddingException e) { } catch (InvalidKeyException e) { } catch (IllegalBlockSizeException e) { } catch (BadPaddingException e) { } catch (ClassNotFoundException e) {
SEnc.java
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream;
import java.security.InvalidKeyException; import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException; import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException;
//基于DES的对称加密算法 public class SEnc {
private static String s; public SEnc(String mingwen) { }
public static String Ees() {
try{
//String s=\ FileInputStream fs=new FileInputStream(\); ObjectInputStream os=new ObjectInputStream(fs); Key k=(Key)os.readObject(); /*
* 创建密码器,Cipher工厂的getInstance()方法中指定加密算法名称, * 反馈模式,填充方案等如DESede/ECB/PKCS5Padding */
Cipher cp=Cipher.getInstance(\); //初始化Cipher对象
cp.init(Cipher.ENCRYPT_MODE, k);
//getBytes()方法中必须指定UTF8字符集,避免跨平台错误 byte[] ptext=s.getBytes(\); for(int i=0;i System.out.print(ptext[i]+\);//加密前的输出 } System.out.println(); byte[] ctext=cp.doFinal(ptext);//进行加密 for(int i=0;i System.out.print(ctext[i]+\);//加密后的输出 } FileOutputStream f2=new FileOutputStream(\); f2.write(ctext); s = ctext.toString(); }catch(FileNotFoundException e){ e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); }catch(IOException e){ }catch(ClassNotFoundException e){ }catch(NoSuchAlgorithmException e){ }catch(NoSuchPaddingException e){ // TODO 自动生成的构造函数存根 s = mingwen; } } } e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); }catch(InvalidKeyException e){ }catch(IllegalBlockSizeException e){ }catch(BadPaddingException e){ return s; SKey_DES.java import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.security.NoSuchAlgorithmException; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; //生成对称秘钥 //对称秘钥生成及对象化保存 public class Skey_DES { public Skey_DES(){ // TODO 自动生成的构造函数存根 } public void Key(){ /* * KeyGenerator类是一个工厂类或者工厂,通过预定义静态方法getInstance() * getInstance()的参数为字符串类型,指定加密算法的名称,可以是 * ,128)、AES(128,192,256)、HmacSHAI(64)、HmacMD5(64) */ try { KeyGenerator kg = KeyGenerator.getInstance(\); kg.init(56);//指定秘钥长度,省略后可采用默认值 SecretKey k=kg.generateKey(); FileOutputStream fs=new FileOutputStream(\);//对象秘 获得KeyGenerator类型的对象 Blowfish(32~448),DES(56)、DESede(112 钥序列化保存 ObjectOutputStream os=new ObjectOutputStream(fs); os.writeObject(k); } } } catch (NoSuchAlgorithmException e) { } e.printStackTrace(); e.printStackTrace(); e.printStackTrace(); }catch (FileNotFoundException e) { }catch (IOException e) {
正在阅读:
信息安全211-09
2018年江苏师范大学传媒与影视学院公共行政学(加试)复试实战预测五套卷05-05
国际私法09-25
四年级数学上册家庭作业10-19
当代中国法学名家02-26
数学的哲学理论和数学教学11-13
大工14秋《工程招投标及合同管理》在线测试1习题及答案04-28
昆虫基础知识12-02
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 安全
- 信息
- 00-hhoby某公司培训制度
- 数模辅修
- 2018新北师大版数学八年级期末专题练习附详细答案
- 广东省危险化学品登记复核工作流程
- 苏大版新闻评论学笔记 六—至十一章
- 博弈论综合测试1-8
- (06)洁净区卫生管理规程
- 大学物理答案 罗益民 北京邮电大学
- 机械电子工程申报书doc-普通高等学校本科专业设置申请表 - 图文
- 小学科学教科版五年级下册第一单元沉与浮《浮力》优质课公开课教案教师资格证面试试讲教案
- 彼得·斯丛狄《现代戏剧理论》读书笔记
- 中国工商银行网上银行客户满意度和忠诚度调查
- 派出所自查自纠工作情况汇报
- 微信聊天记录怎么恢复?iPhone XS恢复微信聊天记录技巧
- 中州杯奖文件
- 苏教版高中语文选修系列《红楼梦》梗概及问题1-10回 Word版含答案
- 2019年整理初中数学八年级上册《平行四边形、菱形、矩形、正方形综合复习1》
- 《数字音频创作》课程教学大纲 - 图文
- 大道之行也练习题
- 《材料腐蚀与电化学测试技术》作业-论文翻译