【graceup系列】--基于Java带数字签名的邮件收发系统
源码+文档 下载地址:http://download.csdn.net/detail/graceup/7817339
效果图:
摘 要
本系统主要是实现邮件系统的安全发送与接收,采用B/S模式,外网邮件服务器使用了免费、开源的支持SMAP协议发送电子邮件和IMAP协议接收电子邮件的javamail邮件服务器。内部邮件系统,采用RSA签名机制的方法达到安全传送的目的。系统首先采用MD5对邮件体生成128位的散列值,即签名文,然后对签名文加密,生成加密的签名文,同邮件体一起发送。在服务端接收到邮件后,提取邮件体和加密的签名文,对邮件体用MD5算法生成签名文,并对加密的签名文解密,两个签名文相比较,如果数据在传送过程中没有被修改,两段签名文应该是相等的。否则,数据是不安全的。
本论文介绍了基于java带数字签名的电子邮件系统,对使用的相关的技术进行了详细的阐述。按照软件开发的生命周期论述了系统分析、概要设计、详细设计和代码实现。具体论述了数字签名在邮件系统中的实现原理。以及邮件系统的其他相关的安全细节进行实现。
关键词:java、邮件系统、数字签名
目录
1、 浅谈数字签名的原理;.... 1
1.1. 数字签名的实现方法... 1
1.2. 公钥密码体制... 1
1.3. 数字签名及数字摘要... 2
1.4. MD5算法原理... 3
1.5. RSA算法原理... 4
1.6. 数字签名过程:... 5
2、 邮件收发系统的基本技术.... 6
2.1. SMTP简单邮件传输协议... 6
2.2. POP3邮局协议... 6
2.3. 邮件传输原理... 7
2.4. 电子邮件的发送和接收... 7
2.5. JavaMail的介绍... 8
2.6. 内部邮件系统与电子邮件系统比较:... 9
3、 构建一个邮件收发系统.... 9
3.1. 需求分析... 9
3.2. 系统总体设计... 11
3.2.1. 系统设计... 11
3.3. 概念结构设计... 12
3.3.1. 系统E-R图如图 所示:... 13
3.4. 数据库设计... 13
3.4.1. 创建数据库及其基本表... 13
3.4.2. 创建基本表名,各表如下:... 14
3.5. 应用程序设计... 14
3.5.1. 用myeclipse建立工程... 15
3.5.2. 设置JDBC与MySQL的连接... 15
3.5.3. 编写各功能模块实现代码... 15
3.5.3.1. 注册功能模块... 17
3.5.3.2. 登录功能模块... 18
3.5.3.3. 密码找回功能模块... 19
3.5.3.4. 写信功能模块... 21
3.5.3.5. 收件箱功能模块... 22
3.5.3.6. 设置代理邮件功能模块... 23
4、 实现数字签名作用到邮件收发系统;.... 25
4.1. 邮件中数据传输的几个安全性需求... 25
4.2. 在邮件系统中实现数字签名... 25
4.3. Java中实现数字签名... 26
4.4. 对邮件进行数字签名... 27
4.5. 收件人对邮件内容的验证... 28
结论....29
参 考 文 献.... 30
1、 浅谈数字签名的原理;
在数字签名中有重要作用的数字摘要是通过一类特殊的散列函数(HASH函数)生成的, 对这些HASH函数的特殊要求是:
4.难以对指定的摘要生成一个报文,而由该报文可以算出该指定的摘要;
数字签名的方法有许多,在本系统中,我们所采用的是用MD5摘要算法对邮件内容进行处理,生成32位的数字摘要,再用 RSA算法进行数字签名。
MD5算法先对输入的数据进行补位,使得数据的长度(以byte为单位)对64求余的结果是56。即数据扩展至LEN=K*64+56个字节,K为整数。
补位方法:补一个1,然后补0至满足上述要求。相当于补一个0x80的字节,再补值为0的字节。这一步里总共补充的字节数为0~63个。
有四个32位整数变量 (A,B,C,D) 用来计算信息摘要,每一个变量被初始化成以下以十六进制数表示的数值,低位的字节在前面。
wordA: 01 23 45 67 word B: 89 ab cd ef
wordC: fe dc ba 98 word D: 76 54 32 10
低位的字节在前面指的是Little Endian平台上内存中字节的排列方式,而在程序中书写时,要写成:
第四步,定义四个MD5基本的按位操作函数:X,Y,Z为32位整数。
F(X,Y,Z) = (X and Y) or (not(X) and Z) G(X,Y,Z) = (X and Z) or (Y and not(Z))
H(X,Y,Z) = X xor Y xorZ I(X,Y,Z) = Y xor (X or not(Z))
再定义四个分别用于四轮变换的函数。设Mj表示消息的第j个子分组(从0到15),<<S表示循环左移S位,则四种操作为:
FF(a,b,c,d,Mj,s,ti)表示a=b+((a+(F(b,c,d)+Mj+ti)<<s)
GG(a,b,c,d,Mj,s,ti)表示a=b+((a+(G(b,c,d)+Mj+ti)<<s)
HH(a,b,c,d,Mj,s,ti)表示a=b+((a+(H(b,c,d)+Mj+ti)<<s)
II(a,b,c,d,Mj,s,ti)表示a=b+((a+(I(b,c,d)+Mj+ti)<<s)
RSA可用于数字签名,方案是用 ( a ) 式签名, ( b )式验证。
在数字签名应用中,首先由发送者身份生成它的私钥和公钥,然后由发送者通过私钥把数据加密后,并将加密后的数据发送给接收者;接收者把发送者加密过的数据通过发送者的共钥进行签名验证。
1、信息发送者使用一单向散列函数(HASH 函数)对信息生成信息摘要;
这是一种与消息认证码结合使用以确保消息完整性的技术。主要使用单向散列函数算法,可用于检验消息的完整性,和通过散列密码直接以文本形式保存等,在java中进行数字签名很简单。
2、 邮件收发系统的基本技术
2.
图2-1 POP3状态转换图
注:服务器A是发送邮件服务器(SMTP),服务器B是接收邮件服务器(POP3/IMAP)
JavaMail是一个100%用Java实现的SMTP和POP3邮件服务器。JavaMail被设计成一个完整的、可移植的企业邮件引擎解决方案,他完全基于目前可用的开放性协议。
虽然JavaMail是Sun的API之一,但它目前还没有被加在标准的java开发工具包中(Java Development Kit),这就意味着在使用前必须另外下载JavaMail文件。
电子邮件要SMTP, POP传输服务 NCP传输服务 NITS X.25传输服务等。
3、 构建一个邮件收发系统
3.
用户可以通过注册时用户名称以及用户安全信息的问题和答案来填写相关信息,如果信息匹配,用户就可以重新设置密码。
用户登陆后,进入邮件系统的主界面,如果用户设置了默认邮件服务器,则列出用户默认邮件服务器上收件箱的所有邮件,在该列表上用户可以选择只显示已读邮件或者未读邮件,或者删除邮件。
用户第一次使用系统的时候,可以添加一个代理的邮件服务器来发外网邮件。邮件服务器的信息包括:完整的登陆帐,登录密码。如果不添加的,就采用系统默认的邮件地址发送外网邮件。
提供一个邮件发送界面,在该界面上可以让用户输入外网邮件发送地址,主题,内容,就可以直接发送外网邮件。
用户登陆的时候自动从默认邮件服务器上收取新邮件,用户可以查看新邮件,对邮件进行查看,删除的操作。
提供一个邮件发送界面,在该界面上可以让用户输入邮件发送地址,主题,内容,可以让用户把邮件保存为草稿,也可以直接发送邮件。
提供一个草稿邮件管理界面,在该界面上可以让用户编辑草稿内容,可以让用户把邮件继续保存为草稿,也可以直接发送邮件。
3.2.1. 系统设计
根据系统分析的结果,具体分析不同实体用户,描述不同实体之间的关系,得出系统数据实体图和E-R图。
3.3.1. 系统E-R图如图 所示:
3.4.1. 创建数据库及其基本表
用mysql的可视化工具:Navicat for MySQL创建数据库及其基本表的主要过程如下:
3.4.2. 创建基本表名,各表如下:
本系统主要使用JSP+Servlet、tomcat服务器技术对系统进行设计和开发。JSP拥有Java程序设计语言“一次编写,各处执行”、“安全性、保密性高”等的特点;
完善的后台管理,管理员不需要懂得任何操作就可以对前台进行控制。
采用Browser/Server三层体系结构,使系统具有很好的可维护性和可重用性。
使用的是在网上下载的java与MySQL连接的API类库:mysql5.1.7-jdbc.jar
public class JdbcUtils {
static StringdriverName = "com.mysql.jdbc.Driver"; // 加载JDBC驱动
static StringdbURL = "jdbc:mysql://localhost:3306/mail";//连接服务器和数据库
static StringuserName = "root"; // 默认用户名
static StringuserPwd = "123"; // 密码
static{
try{
Class.forName(driverName);
}
catch(Exception e){
throw newExceptionInInitializerError(e);
}
}
/**
* 获取数据库的连接
* @return
* @throws SQLException
*/
public static ConnectiongetConnection()throws SQLException
{
return DriverManager.getConnection(dbURL,userName, userPwd);
}
/**
* 释放数据库的连接
*/
public static void release(Connectionconn,Statement st,ResultSet rs){
if(rs!=null){
try{
rs.close();
}
catch(Exception e){
e.printStackTrace();
}
rs=null;
}
if(st!=null){
try{
st.close();
}
catch(Exception e){
e.printStackTrace();
}
st=null;
}
if(conn!=null){
try{
conn.close();
}
catch(Exception e){
e.printStackTrace(); }
此模块主要功能是用于注册新用户,用户输入名称、密码、安全问题、答案(这两个用于找回密码),如下图所示:
在此功能用到的安全技术是MD5压缩用户的密码和安全问题的答案,就算是数据库管理员也无法获取到某个用户的密码信息。
MessageDigest md5=MessageDigest.getInstance("MD5");
BASE64Encoder base64=new BASE64Encoder();
returnbase64.encode(md5.digest(s.getBytes("utf-8")));
request.setCharacterEncoding("UTF-8");
Stringusername = request.getParameter("username");
Stringpasswordtmp = request.getParameter("password");
Stringpassword = MD5.md5Encrypt(passwordtmp);
Useruser=ud.login(username, password);
if(user!=null){ request.getSession().setAttribute("user", user);
response.sendRedirect(request.getContextPath()+ "/main/main.jsp");
request.setAttribute("message","登录失败!!"); }
request.setAttribute("message","用户名或密码错误!!");
request.getRequestDispatcher("/message.jsp").forward(request,response);
User user= ud.findPwd(username);
request.getSession().setAttribute("user", user);
if (user ==null) { request.getRequestDispatcher("/pwd/pwd2.jsp").forward(request,
} else if(user.getQuestion() == null) {
request.getRequestDispatcher("/pwd/pwd.jsp").forward(request,
request.getRequestDispatcher("/pwd/pwd1.jsp").forward(request,
request.setAttribute("message","找回失败!!");
此模块主要功能是用于发送内部邮件,用户输入邮件发送地址,主题,内容后,可以把邮件保存为草稿,也可以直接发送邮件。如下图所示:
request.setAttribute("message","保存成功!!");
request.getRequestDispatcher("/message.jsp").forward(request,response); return; }
request.setAttribute("message","发送失败!!"); }
request.setAttribute("message","发送成功!!");
request.getRequestDispatcher("/message.jsp").forward(request,response);
此模块主要功能是用于用户登陆的时候自动从默认邮件服务器上收取新邮件,用户可以查看新邮件,对邮件进行查看,删除的操作。如下图所示:
QueryInfo info = WebUtils.request2Bean(request,QueryInfo.class);
Useruser=(User) request.getSession().getAttribute("user");
String username=user.getUsername();
MailServiceservice = new MailService();
PageBeanpagebean = service.pageQueryReceive(info,username);
request.setAttribute("pagebean", pagebean);
request.getRequestDispatcher("/listreceive.jsp").forward(request,response);
request.setAttribute("message","查看收信箱失败!!");
request.getRequestDispatcher("/message.jsp").forward(request,response);
MailSenderInfomailInfo = new MailSenderInfo();
String[] temp=from.split("@");
StringBuffer buffer=new StringBuffer();
String result=buffer.append(before).append(temp[1]).toString();
mailInfo.setMailServerHost(result);
mailInfo.setMailServerPort("25");
mailInfo.setPassword(password);//您的邮箱密码
mailInfo.setFromAddress(from);
SimpleMailSender sms = new SimpleMailSender();
sms.sendTextMail(mailInfo);//发送文体格式
4、 实现数字签名作用到邮件收发系统;
1. 数据的保密性:用于防止非法用户进入系统及合法用户对系统资源的非法使用;通过对一些敏感的数据文件进行加密来保护系统之间的数据交换,防止除接收方之外的第三方截获数据及即使获取文件也无法得到其内容。
2. 数据的完整性:防止非法用户对进行交换的数据进行无意或恶意的修改、插入,防止交换的数据丢失等。
3. 数据的不可否认性:对数据和信息的来源进行验证,以确保数据由合法的用户发出;防止数据发送方在发出数据后又加以否认;同时防止接收方在收到数据后又否认曾收到过此数据及篡改数据。
使用公钥与私钥的目的就是实现安全的电子邮件,必须实现如下目的:
1.我发送给你的内容必须加密,在邮件的传输过程中不能被别人看到。
比如说,我要给你发送一个加密的邮件。首先,我必须拥有你的公钥,你也必须拥有我的公钥。
首先,我用你的公钥给这个邮件加密,这样就保证这个邮件不被别人看到,而且保证这个邮件在传送过程中没有被修改。你收到邮件后,用你的私钥就可以解密,就能看到内容。
其次我用我的私钥给这个邮件加密,发送到你手里后,你可以用我的公钥解密。因为私钥只有我手里有,这样就保证了这个邮件是我发送的。
public List<String> getKey(String infor) {
List<String> list = new ArrayList<String>();
byte[]info = infor.getBytes();
KeyPairGenerator myKeyGen =KeyPairGenerator.getInstance("RSA");
KeyPair myKeyPair =myKeyGen.generateKeyPair();
System.out.println("得到RSA密钥对");
PublicKey publickey = keys.getPublic();//获得生成的公钥
PrivateKey privatekey =keys.getPrivate();//获得生成的私钥
String pubkey = StringAndByte.bytesToHexStr(publickey
.getEncoded());// 把公钥转化成String型
String prikey = StringAndByte.bytesToHexStr(privatekey
.getEncoded());// 把私钥转化成String型
public String signature(String infor, String prikey)throws Exception {
byte[] info = infor.getBytes();
Signature mySig = Signature.getInstance("SHA1WithRSA");// 用指定算法产生签名对象
byte[] pubk = StringAndByte.hexStrToBytes(prikey);//将私钥转化成十六进制
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(pubk);
keyf = KeyFactory.getInstance("RSA");
mypubkey =keyf.generatePrivate(priPKCS8);
mySig.initSign(mypubkey); // 用私钥初始化签名对象
mySig.update(info); // 将待签名的数据传送给签名对象(须在初始化之后)
byte[] sigResult = mySig.sign();// 返回签名结果字节数组
sigResults=StringAndByte.bytesToHexStr(sigResult);
public boolean check(String infor, String sigResults, String pubkey)
byte[] info = infor.getBytes();
Signature mySig = Signature.getInstance("SHA1WithRSA");// 用指定算法产生签名对象
byte[] pubk = StringAndByte.hexStrToBytes(pubkey);//将公钥转化成十六进制
X509EncodedKeySpec priPKCS8=new X509EncodedKeySpec(pubk);
keyf = KeyFactory.getInstance("RSA");
mypubkey = keyf.generatePublic(priPKCS8);
byte[] sigResultb=StringAndByte.hexStrToBytes(sigResults);
mySig.initVerify(mypubkey); //使用公钥初始化签名对象,用于验证签名
boolean verify = mySig.verify(sigResultb);// 得到验证结果
从用户的数据库中取出用户的公钥和私钥。将公钥和使用私钥签名后生成的文摘发送到服务器,然后保存到数据库。具体实现代码如下:
User user=(User) request.getSession().getAttribute("user"); String privatekey = user.getPrivatekey(); StringBuffer buffer = new StringBuffer(); String sum=buffer.append(fromname).append(toname).append(subject).append(content).toString(); RSA rsa=new RSA(); String summary=rsa.signature(sum, privatekey); Mail mail=new Mail(); mail.setFromname(fromname); mail.setToname(toname); mail.setSubject(subject); mail.setContent(content); mail.setSummary(summary); |
收件人收到发来签名后的摘要以及邮件原始内容,然后从数据库中取出发件人的公钥,对邮件进行验证,如果验证的结果和摘要的一样,则“显示数字签名正确”,否则显示“邮件已破坏”。具体实现代码如下:
Mail mail = (Mail) request.getAttribute("c"); String fromname = mail.getFromname(); String content = mail.getContent(); String summary = mail.getSummary(); String toname=mail.getToname(); String subject=mail.getSubject(); UserDao ud = new UserDao(); User user = ud.findPwd(fromname); StringBuffer buffer = new StringBuffer(); String sum=buffer.append(fromname).append(toname).append(subject).append(content).toString(); String publickey = user.getPublickey(); RSA rsa = new RSA(); boolean check =false; try { check = rsa.check(sum, summary, publickey); System.out.println(check); } catch (Exception e) { } %> <% if (check) { %> 此邮件数字签名是正确的。 <% }else { %> 此邮件已破坏。 <% } %> |
结论
本系统可以实现邮件收发功能。用户只要在本系统注册,填入相关的信息,成功注册为本系统用户后,再次输入正确的用户名和密码,登陆系统,进入系统主界面,就可以发送邮件,或者读取邮件。
本系统操作使用方便,界面简洁。此系统的功能界面是模拟163邮箱实现的,用户使用起来,感觉比较熟悉,可以尽快上手。
参 考 文 献
[1] 刘晓华.JSP 应用开发详解.北京电子工业出版社.2005
[2] 黄晓东著.JAVA课程设计案例精编.河南:中国水利水电出版社.2004.7
[3] 张海藩.软件工程导论(第五版)学习辅导.清华大学出版社,2008年9期.
[4] 张敏. 数据库安全研究现状与展望[J].中国科学院院刊,2011,03:303-309.
[5] 李慧. 密文数据库安全强度分析和数据库加密算法、子密钥生成研究[D].贵州大学,2008.
[6] 张先红.数字签名原理及应用[M].第一版.北京:机械工业出版社,2004.1:12-196.
[7] 谈娴茹.基于DES和RSA的网络数据安全系统[J] .中国民航学院学报,2003,
[8] 宋震.密码学[M].北京:中国水利水电出版社. 2002:87-151.
[9] 任伟.现代密码学[J].北京:北京邮电大学出版社.2011.
[10] 崔用明.邮件接收协议POP3的探讨[J] .机械研究与应用,2005,18(4) :120-120.
【graceup系列】--基于Java带数字签名的邮件收发系统相关推荐
- 基于java的数字签名技术在电子政务中的应用
肖蕾 杨世平 摘要 本文介绍了数字签名技术在电子政务中的应用,传统的数字签名技术都是基于非对称的密码算法,原文以明文的方式传送,在这种方式下,原文的安全性受到了极大的威胁,因此,本文 ...
- 基于JAVA高校实习管理平台系统计算机毕业设计源码+数据库+lw文档+系统+部署
基于JAVA高校实习管理平台系统计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA高校实习管理平台系统计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S架构 ...
- 基于Java毕业设计学生用品采购系统源码+系统+mysql+lw文档+部署软件
基于Java毕业设计学生用品采购系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计学生用品采购系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开 ...
- 基于Java毕业设计医院门诊分诊系统源码+系统+mysql+lw文档+部署软件
基于Java毕业设计医院门诊分诊系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计医院门诊分诊系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开 ...
- dispatch作用 react_「React系列」手把手带你撸后台系统(Redux与路由鉴权)
[React系列]手把手带你撸后台系统(Redux与路由鉴权) 来源:https://juejin.im/post/5d9b5ddee51d45781b63b8f7 上一篇我们介绍了系统架构,这一篇将 ...
- 基于Java的设计开题报告_基于Java的电子邮件的收发系统的设计与实现开题报告...
基于Java的电子邮件的收发系统的设计与实现开题报告 (8页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.90 积分 开题报告 基于 Java 的电子 ...
- java中ssm付款代码_基于Java+SSM的网上订餐系统、基于JavaWeb的网上订餐系统
需求分析 基于Java+SSM框架实现一个校园点餐系统,包括用户端和管理员端; 前台主要功能有用户注册, 用户登录, 我的购物车.我的订单.商品评论.校园资讯等; 管理员端主要功能有:用户管理.商品管 ...
- 基于JAVA高铁在线购票系统计算机毕业设计源码+数据库+lw文档+系统+部署
基于JAVA高铁在线购票系统计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA高铁在线购票系统计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S架构 开发语 ...
- 基于JAVA工作流流程编辑OA系统计算机毕业设计源码+数据库+lw文档+系统+部署
基于JAVA工作流流程编辑OA系统计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA工作流流程编辑OA系统计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S ...
最新文章
- 安装Rabbitmq脚本
- struts2 Action 通过Spring管理, 并通过Spring的方式读取配置文件
- html调整文字位在基线显示,html – 将标题对齐到相同的基线,无论后续文字是什么?...
- 股东痛斥联想管理层:都是帅哥 但业绩差
- Visual Studio 2008 每日提示(一)
- 计算机网络上机指导,计算机网络上机指导书.pdf
- CSND Markdown模板
- 月入30K 的电子工程师很常见吗,需要具备啥素质才配得上这个薪资
- 大工《画法几何与机械制图》课程设计大作业离线作业
- 网易蜗牛读书与微信读书竞品分析
- KYLO的JVM知识总结
- 英文单词之说文解字(9)
- [UE4]大型户外场景制作教程
- 【嵌入式】CPU性能提升:流水线机制
- IE浏览器下载文本文件(txt,csv等)
- C51接入OneNET-实现数据上传和命令下发
- 锁相环PLL的工作原理
- H5游戏开发很重要,后台可控可测,超圣刷流水,招代理稳赢
- C#关键字之internal详解
- 【Java案例】为新员工分配部门