公钥和私钥就是俗称的不对称加密方式,使用公钥与私钥的目的就是实现安全的电子邮件,必须实现如下目的:
1.我发送给你的内容必须加密,在邮件的传输过程中不能被别人看到。
2.必须保证是我发送的邮件,不是别人冒充我的。
要达到这样的目标必须发送邮件的两人都有公钥和私钥。
公钥,就是给大家用的,你可以通过电子邮件发布,可以通过网站让别人下载,公钥其实是用来加密/验章用的。私钥,就是自己的,必须非常小心保存,最好加上密码,私钥是用来解密/签章,首先就Key的所有权来说,私钥只有个人拥有。公钥与私钥的作用是:用公钥加密的内容只能用私钥解密,用私钥加密的内容只能用公钥解密。
比如说,我要给你发送一个加密的邮件。首先,我必须拥有你的公钥。
首先,我用你的公钥给这个邮件加密,这样就保证这个邮件不被别人看到,而且保证这个邮件在传送过程中没有被修改。你收到邮件后,用你的私钥就可以解密,就能看到内容。
其次我用我的私钥给这个邮件加密,发送到你手里后,你可以用我的公钥解密。因为私钥只有我手里有,这样就保证了这个邮件是我发送的。
当A->B资料时,A会使用B的公钥加密,这样才能确保只有B能解开,否则普罗大众都能解开加密的讯息,就失去了资料的保密性。验证方面则是使用签验章的机制,A传资料给大家时,会以自己的私钥做签章,如此所有收到讯息的人都可以用A的公钥进行验章,便可确认讯息是由A发出来的了。


源码+文档 下载地址: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、  浅谈数字签名的原理;

1.1.    数字签名的实现方法

实现数字签名有很多方法,目前数字签名采用较多的是公钥加密技术,如基于RSADate Security 公司的PKCS( Public Key CryptographyStandards )、Digital Signature Algorithm、x.509、PGP(Pretty Good Privacy). 1994年美国标准与技术协会公布了数字签名标准(DSS)而使公钥加密技术广泛应用。公钥加密系统采用的是非对称加密算法。

1.2.    公钥密码体制

1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,在此新思想的基础上,很快出现了公钥密码体制。

公钥密码体制是现代密码学的最重要的发明和进展。一般理解密码学就是保护信息传递的机密性。但这仅仅是当今密码学主题的一个方面。对信息发送与接收人的真实身份的验证、对所发出/接收信息在事后的不可抵赖以及保障数据的完整性是现代密码学主题的另一方面。公钥密码体制对这两方面的问题都绘出了出色的解答,并正在继续产生许多新的思想和方案。在公钥密码体制中加密密钥不同于解密密钥,并且从其中一个很难推断出另一个(相对于“对称密码技术”,这种方法也叫做“非对称密码技术”)。其中一个密钥公之于众,谁都可以用,称为“公开密钥”,另一个密钥由用户自己保存,称为“秘密密钥”。这两个密钥之间存在着相互依存关系:即用其中任一个密钥加密的信息只能用另一个密钥进行解密。

若以公开密钥(公钥)作为加密密钥,以用户秘密密钥(私钥)作为解密密钥,则可实现多个用户加密的信息只能由一个用户解读;反之,以用户私钥作为加密密钥而以公钥作为解密密钥,则可实现一个用户加密的信息由多个用户解读。

1.3.   数字签名及数字摘要

目前的数字签名是建立在公钥密码体制基础上,它是公钥加密技术的另一类应用。数字签名是指用户用自己的私钥对报文的数字摘要(由散列函数产生)进行加密后所得的数据。数字签名从技术上标识了发信者对该电文的数字指纹的责任。因为发信者的私钥只有他本人才有,所以他一旦完成了签名便保证了发信人无法抵赖曾发过该信息(即不可抵赖性)。经验证无误的签名电文同时也确保信息报文在经签名后未被篡改(即完整性)。数字签名的过程如图1-1所示。

图1-1 数字签名

当信息接收者收到报文后,使用信息发送者的公钥对附在原始信息后的数字签名进行解密后获得数字摘要,并通过与自己用收到的原始数据产生的数字摘要对照。如果完全相符,文件内容的完整性、正确性和签名的真实性都得到了保障。实现过程如图1-2所示。

图1-2 验证数字签名

在数字签名中有重要作用的数字摘要是通过一类特殊的散列函数(HASH函数)生成的, 对这些HASH函数的特殊要求是:

1.接受的输入报文数据没有长度限制;

2.对任何输入报文数据生成固定长度的摘要输出;

3.从报文能方便地算出摘要;

4.难以对指定的摘要生成一个报文,而由该报文可以算出该指定的摘要;

5.难以生成两个不同的报文具有相同的摘要。

常用的HASH算法有MD2、MD5、SHA·1。

数字签名的方法有许多,在本系统中,我们所采用的是用MD5摘要算法对邮件内容进行处理,生成32位的数字摘要,再用 RSA算法进行数字签名。

1.4.   MD5算法原理

MD5的全称是message-digestalgorithm 5(信息-摘要算法),它是经MD2、MD3和MD4发展而来。它的作用是让大容量信息在用数字签名软件签署私人密匙前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数)。

MD5算法的编程思路

第一步,补位:

MD5算法先对输入的数据进行补位,使得数据的长度(以byte为单位)对64求余的结果是56。即数据扩展至LEN=K*64+56个字节,K为整数。

补位方法:补一个1,然后补0至满足上述要求。相当于补一个0x80的字节,再补值为0的字节。这一步里总共补充的字节数为0~63个。

第二步,附加数据长度:

用一个64位的整数表示数据的原始长度(以bit为单位),将这个数字的8个字节按低位的在前,高位在后的顺序附加在补位后的数据后面。这时,数据被填补后的总长度为:LEN = K*64+56+8=(K+1)*64 Bytes。

第三步,初始化MD5参数:

有四个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平台上内存中字节的排列方式,而在程序中书写时,要写成:

A=0x67452301   B=0xefcdab89

C=0x98badcfe    D=0x10325476

第四步,定义四个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)

第五步,对输入数据作变换。

处理数据,N是总的字节数,以64个字节为一组,每组作一次循环,每次循环进行四轮操作。要变换的64个字节用16个32位的整数数组M[0 …… 15]表示。而数组T[1 …… 64]表示一组常数, T为4294967296*abs(sin(i))的32位整数部分,i的单位是弧度,i的取值从1到64。

第六步,测试结果。

1.5.   RSA算法原理

1978年就出现了这种算法,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。RSA的安全性一直未能得到理论上的证明。RSA的安全性依赖于大数分解。公钥和私钥都是两个大素数(大于 100个十进制位)的函数。据猜测,从一个密钥和密文推断出明文的难度等同于分解两个大素数的积。 RSA密钥对的产生过程如下:

选择两个大素数,p 和q 。计算: n = p * q

图1-3 数字签名过程

然后随机选择加密密钥e,要求 e 和 ( p - 1 ) * ( q - 1 ) 互质。最后,利用Euclid 算法计算解密密钥d, 满足 e * d = 1 ( mod ( p - 1 ) * ( q -1 ) ),其中n和d也要互质。数e和n是公钥,d是私钥。两个素数p和q不再需要,应该丢弃,不要让任何人知道。 加密信息 m(二进制表示)时,首先把m分成等长数据块 m1 , m2,… , mi ,块长s,其中 2s <= n, s 尽可能的大。对应的密文是:

ci = mie ( mod n )        ( a )

解密时作如下计算:

mi= cid ( mod n )        ( b )

RSA可用于数字签名,方案是用 ( a ) 式签名, ( b )式验证。

在数字签名应用中,首先由发送者身份生成它的私钥和公钥,然后由发送者通过私钥把数据加密后,并将加密后的数据发送给接收者;接收者把发送者加密过的数据通过发送者的共钥进行签名验证。

1.6.    数字签名过程:

1、信息发送者使用一单向散列函数(HASH 函数)对信息生成信息摘要;

2、信息发送者使用自己的私钥签名信息摘要;

3、信息发送者把信息本身和已签名的信息摘要一起发送出去;
4、信息接收者通过使用与信息发送者使用的同一个单向散列函数(HASH 函数)对接收的信息本身生成新的信息摘要,再使用信息发送者的公钥对信息摘要进行验证,以确认信息发送者的身份和信息是否被修改过。

这是一种与消息认证码结合使用以确保消息完整性的技术。主要使用单向散列函数算法,可用于检验消息的完整性,和通过散列密码直接以文本形式保存等,在java中进行数字签名很简单。

2、 邮件收发系统的基本技术

2.    

2.1.    SMTP简单邮件传输协议

SMTP是基于TCP服务的应用层协议,由RFC821所定义。协议规定了客户与服务器之间双向通信的规则,及信封信息的传递。SMTP是工作在两种情况下:一是电子邮件从客户机传输到服务器;二是从某一个服务器传输到另一个服务器。

SMTP是个请求/响应协议,命令和响应都是基于ASCII文本,并以CR和LF符结束。每个命令都是简单的命令名,后面接着参数。响应包括一个表示返回状态的三位数字代码。SMTP使用众所周知的TCP端口25。

2.2.   POP3邮局协议

POP3客户向POP3服务器发送命令并等待响应,POP3命令采用命令行形式,用ASCII码表示。服务器响应是由一个单独的命令行组成或多个命令行组成,响应第一行以ASCII文本+OK或+ERR(OK指成功,ERR指失败)指出相应的操作状态是成功还是失败。

在POP3协议中有三种状态,认证状态,处理状态和更新状态。当客户机与服务器建立连接时,客户机向服务器发送自己身份(这里指的是账户和密码)并由服务器成功确认,即系统由认可状态转入处理状态,在完成列出未读邮件等相应的操作后系统发出quit命令,退出处理状态进入更新状态,开始下载未阅读过的邮件到计算机本地之后最后重返认证状态确认身份后断开与服务器的连接。具体原理如下图1-3所示。

图2-1 POP3状态转换图

2.3.    邮件传输原理

在Internet上将一段文本信息从一台计算机传送到另一台计算机上,可通过两种协议来完成,即 SMTP和POP3。SMTP是Internet协议集中的邮件标准。在Internet上能够接收电子邮件的服务器都有SMTP。电子邮件在发送前,发件方的SMTP服务器与接收方的SMTP服务器联系,确认接收方准备好了,则开始邮件传递;若没有准备好,发送服务器便会等待,并在一段时间后继续与接收方邮件服务器联系。这种方式在Internet上称为“存储——转发”方式。POP3可允许E-mail客户向某一SMTP服务器发送电子邮件,另外,也可以接收来自SMTP服务器的电子邮件。换句话说,电子邮件在客户PC机与服务提供商之间的传递是通过P0P3来完成的,而电子邮件在 Internet上的传递则是通过SMTP来实现。如图所示:

图2-2 邮件传输原理

注:服务器A是发送邮件服务器(SMTP),服务器B是接收邮件服务器(POP3/IMAP)

2.4.    电子邮件的发送和接收

电子邮件在Internet上发送和接收的原理可以很形象地用我们日常生活中邮寄包裹来形容:当我们要寄一个包裹的时候,我们首先要找到任何一个有这项业务的邮局,在填写完收件人姓名、地址等等之后包裹就寄出而到了收件人所在地的邮局,那么对方取包裹的时候就必须去这个邮局才能取出。同样的,当我们发送电子邮件的时候,这封邮件是由邮件发送服务器(任何一个都可以)发出,并根据收信人的地址判断对方的邮件接收服务器而将这封信发送到该服务器上,收信人要收取邮件也只能访问这个服务器才能够完成。

2.5.    JavaMail的介绍

本邮件系统调用外网邮件时。利用JavaMail来实现。

JavaMail是一个100%用Java实现的SMTP和POP3邮件服务器。JavaMail被设计成一个完整的、可移植的企业邮件引擎解决方案,他完全基于目前可用的开放性协议。

以下是关于JavaMail的一些基本知识:

JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它可以方便地执行一些常用的邮件传输。我们可以基于JavaMail开发出类似于Microsoft Outlook的应用程序。

虽然JavaMail是Sun的API之一,但它目前还没有被加在标准的java开发工具包中(Java Development Kit),这就意味着在使用前必须另外下载JavaMail文件。

JavaMail包中用于处理电子邮件的核心类是:Session,Message,Address,Authenticator,Transport,Store,Folder等。Session定义了一个基本的邮件会话,它需要从Properties中读取类似于邮件服务器,用户名和密码等信息。

Javax.mail.Session:Session 类定义了一个基本邮件会话(session),是Java Mail API最高层入口类。所有其它类都是经由这个session 才得以生效。Session 对象用 Java.util.Properties 对象获取信息,如邮件服务器、用户名、密码及整个应用程序中共享的其它信息。
  Javax.mail.Message:一旦获得Session 对象,就可以继续创建要发送的消息。这由 Message 类来完成。因为 Message 是个抽象类,必需用一个子类,多数情况下为 Javax.mail.internet.MimeMessage。MimeMessage 是个能理解 MIME 类型和头的电子邮件消息,正如不同 RFC 中所定义的。虽然在某些头部域非 ASCII 字符也能被译码,但 Message 头只能被限制为用 US-ASCII 字符。
  Javax.mail.Address:一旦您创建了 Session 和 Message,并将内容填入消息后,就可以用 Address 确定信件地址了。和 Message 一样,Address 也是个抽象类。您用的是 Javax.mail.internet.InternetAddress类。
  Javax.mail. Authenticator:与Java.net 类一样,JavaMail API 也可以利用Authenticator 通过用户名和密码访问受保护的资源。对于JavaMail API 来说,这些资源就是邮件服务器。JavaMail Authenticator 在 Javax.mail 包中,而且它和 Java.net 中同名的类 Authenticator 不同。两者并不共享同一个 Authenticator,因为JavaMail API 用于 Java 1.1,它没有 Java.net 类别。
要使用 Authenticator,先创建一个抽象类的子类,并从 getPasswordAuthentication() 方法中返回PasswordAuthentication 实例。创建完成后,您必需向 session 注册 Authenticator。然后,在需要认证的时候,就会通知Authenticator。您可以弹出窗口,也可以从配置文件中(虽然没有加密是不安全的)读取用户名和密码,将它们作为 PasswordAuthentication 对象返回给调用程序。
  Javax.mail.Transport:消息发送的最后一部分是使用 Transport 类。这个类用协议指定的语言发送消息(通常是 SMTP)。它是抽象类,它的工作方式与 Session 有些类似。仅调用静态 send() 方法,就能使用类的 缺省版本:Transport.send(message);或者,读者也可以从针对自己的协议的会话中获得一个特定的实例,传递用户名和密码(如果不必要就不传),发送消息,然后关闭连接。
  Javax.mail.Store:Store类实现特定邮件协议上的读、写、监视、查找等操作。通过Javax.mail.Store类可以访问Javax.mail.Folder类。
  Javax.mail.Folder:Folder类用于分级组织邮件,并提供照Javax.mail.Message格式访问email的能力。

2.6.    内部邮件系统与电子邮件系统比较

电子邮件要SMTP, POP传输服务 NCP传输服务 NITS X.25传输服务等。

内部邮件不要,内部邮件在同一服务器,同一 数据库中,用户在系统用B/S模式操作,数据从服务器到系统,不要特殊端口。内部 邮件管理主要功能是发送与接受内部邮件,发送与接受内部邮件(外部邮件服务器必须支持pop3),邮件需要存入数据库,以便今后浏览查询。内部邮件的网络结构如下图所示:

图2.3内部邮件服务器构架

3、 构建一个邮件收发系统

3.    

3.1.    需求分析

电子邮件作为Internet最为广泛的应用之一。不仅在普通人的日常生活中,而且,已经成为现代企业内外信息交流的必备工具,据统计Internet上有30%的业务是与电子邮件有关的。企业拥有自己的邮件系统,不仅能够提升企业形象,而且更重要的是能为企业带来实际效益。当然作为一个邮件系统要考虑多方面,比如稳定性、安全性等其他一些因素。Java为实现这种功能提供了丰富的类库。

让用户可以方便地管理邮件服务器上自己的邮件,方便地发送邮件。要达到这个目的,要把用户的相关个人信息数据保存下来,但是从安全性的角度来看,我们需要把用户密码以及其它的一些敏感信息用MD5压缩后再保存下来。

通过上面的分析,邮件系统的主要功能需求分析描述如下:

1. 注册新用户

由于是一个支持多用户的应用,在使用的时候需要有一个登陆的过程,而在应用刚开始提供给使用者使用的时候,不应该规定使用者将以什么样的帐号登陆,所以需要在登陆界面上提供一个给使用者自己注册新用户的功能,这样可以创建应用的用户,保存用户的信息,为登陆做好准备。

1. 找回用户密码

用户可以通过注册时用户名称以及用户安全信息的问题和答案来填写相关信息,如果信息匹配,用户就可以重新设置密码。

3.用户登陆

用户登陆后,进入邮件系统的主界面,如果用户设置了默认邮件服务器,则列出用户默认邮件服务器上收件箱的所有邮件,在该列表上用户可以选择只显示已读邮件或者未读邮件,或者删除邮件。

4. 修改外网邮件服务器

用户第一次使用系统的时候,可以添加一个代理的邮件服务器来发外网邮件。邮件服务器的信息包括:完整的登陆帐,登录密码。如果不添加的,就采用系统默认的邮件地址发送外网邮件。

5. 发送外网邮件

提供一个邮件发送界面,在该界面上可以让用户输入外网邮件发送地址,主题,内容,就可以直接发送外网邮件。

6. 接收邮件

用户登陆的时候自动从默认邮件服务器上收取新邮件,用户可以查看新邮件,对邮件进行查看,删除的操作。

7. 发送邮件

提供一个邮件发送界面,在该界面上可以让用户输入邮件发送地址,主题,内容,可以让用户把邮件保存为草稿,也可以直接发送邮件。

8. 草稿邮件管理

提供一个草稿邮件管理界面,在该界面上可以让用户编辑草稿内容,可以让用户把邮件继续保存为草稿,也可以直接发送邮件。

3.2.    系统总体设计

3.2.1.     系统设计

从模拟用户的角度进行分析,对于一个邮件的系统,首先要确定其功能是什么,也就是用户想要系统做什么工作。有以上需求分析可确定需要建立的模块有:用户注册、用户登录、用户管理、邮件服务器信息管理、邮件管理等。由此分析如下图:

图3.1  系统功能结构示意图

3.3.   概念结构设计

根据系统分析的结果,具体分析不同实体用户,描述不同实体之间的关系,得出系统数据实体图和E-R图。

用户实体属性图如图 所示:

图3.2 用户实体属性图

图3.3 邮件实体属性图

3.3.1.     系统E-R图如图 所示:

图3.4 系统E-R图

3.4.   数据库设计

3.4.1.     创建数据库及其基本表

用mysql的可视化工具:Navicat for MySQL创建数据库及其基本表的主要过程如下:

(1)创建新的数据库—mail

图3.5 建库过程

3.4.2.     创建基本表名,各表如下:

图3.6 用户表

图3.7 邮件表

3.5.   应用程序设计

本系统主要使用JSP+Servlet、tomcat服务器技术对系统进行设计和开发。JSP拥有Java程序设计语言“一次编写,各处执行”、“安全性、保密性高”等的特点;

完善的后台管理,管理员不需要懂得任何操作就可以对前台进行控制。

采用Browser/Server三层体系结构,使系统具有很好的可维护性和可重用性。

Web服务器采用的是Apache的Tomcat应用服务器,它是一个比较完善的、开放的轻量级Web应用服务器,性能优良,配置和部署方便。它严格地遵循普遍流行的开放标准。因此,本系统部署在公网后,只要能上网的地方就能使用本系统。

3.5.1.  用myeclipse建立工程

图3.8 新建java web 工程

3.5.2.设置JDBC与MySQL 的连接

使用的是在网上下载的java与MySQL连接的API类库:mysql5.1.7-jdbc.jar

3.5.3.  编写各功能模块实现代码

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();        }

3.5.3.1. 注册功能模块

此模块主要功能是用于注册新用户,用户输入名称、密码、安全问题、答案(这两个用于找回密码),如下图所示:

图3.9  注册界面

在此功能用到的安全技术是MD5压缩用户的密码和安全问题的答案,就算是数据库管理员也无法获取到某个用户的密码信息。

主要代码:

public class MD5 {

public static Stringmd5Encrypt(String s) throwsUnsupportedEncodingException, NoSuchAlgorithmException {

MessageDigest md5=MessageDigest.getInstance("MD5");

BASE64Encoder base64=new BASE64Encoder();

returnbase64.encode(md5.digest(s.getBytes("utf-8")));

}

3.5.3.2. 登录功能模块

此模块主要功能是用于登录本系统,首先将从前台页面提交的用户名和密码进行接受,之后在后台用MD5对密码进行处理,按照用户名在数据库中进行查询如果查到该用户则将该用户的密码全都取出来,判断从数据库中读出的密码与登录时输入的用MD5压缩后密码是否配比上,若两个密码相同可以进入邮箱,否则输出密码错误。如下图所示:

图3.10  登陆界面

图3.11  邮箱首页界面

主要代码:

try {

request.setCharacterEncoding("UTF-8");

Stringusername = request.getParameter("username");

Stringpasswordtmp = request.getParameter("password");

Stringpassword = MD5.md5Encrypt(passwordtmp);

UserDaoud = new UserDao();

Useruser=ud.login(username, password);

if(user!=null){   request.getSession().setAttribute("user", user);

response.sendRedirect(request.getContextPath()+ "/main/main.jsp");

return;              }

} catch (Exception e) {

e.printStackTrace();

request.setAttribute("message","登录失败!!");       }

request.setAttribute("message","用户名或密码错误!!");

request.getRequestDispatcher("/message.jsp").forward(request,response);

3.5.3.3. 密码找回功能模块

此模块主要功能是用于找回密码,用户可以根据用户的名称填写安全问题的答案等相关信息,这个的安全问题的答案也是经过MD5压缩的,如果填写不符合,也不能进行下一步的操作。如果填写正确的话,用户就可以设置新的密码,如下图所示:

图3.12  找回密码界面

图3.13  重新设置密码界面

主要代码:

UserDao ud = new UserDao();

User user= ud.findPwd(username);

request.getSession().setAttribute("user", user);

if (user ==null) {             request.getRequestDispatcher("/pwd/pwd2.jsp").forward(request,

response);

} else if(user.getQuestion() == null) {

request.getRequestDispatcher("/pwd/pwd.jsp").forward(request,

response);

}else{

request.getRequestDispatcher("/pwd/pwd1.jsp").forward(request,

response);        }

} catch (Exception e) {

e.printStackTrace();

request.setAttribute("message","找回失败!!");

3.5.3.4. 写信功能模块

此模块主要功能是用于发送内部邮件,用户输入邮件发送地址,主题,内容后,可以把邮件保存为草稿,也可以直接发送邮件。如下图所示:

图3.14  写信界面

主要代码:

Mail mail=new Mail();

mail.setFromname(fromname);

mail.setToname(toname);

mail.setSubject(subject);

mail.setContent(content);

mail.setSummary(summary);

if(type==null){

mail.setFromtype("send");

}else{

mail.setFromtype(type);

MailDaomd = new MailDao();

md.add(mail);

request.setAttribute("message","保存成功!!");

request.getRequestDispatcher("/message.jsp").forward(request,response);           return;           }

MailDaomd = new MailDao();

md.add(mail);

} catch (Exception e) {

e.printStackTrace();

request.setAttribute("message","发送失败!!");       }

request.setAttribute("message","发送成功!!");

request.getRequestDispatcher("/message.jsp").forward(request,response);

3.5.3.5. 收件箱功能模块

此模块主要功能是用于用户登陆的时候自动从默认邮件服务器上收取新邮件,用户可以查看新邮件,对邮件进行查看,删除的操作。如下图所示:

图3.15  查看收件列表界面

图3.16  查看邮件界面

主要代码:

try{

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);

}catch (Exception e) {

e.printStackTrace();

request.setAttribute("message","查看收信箱失败!!");

request.getRequestDispatcher("/message.jsp").forward(request,response);

3.5.3.6. 设置代理邮件功能模块

此模块主要功能是用于添加一个代理的邮件服务器来发外网邮件。邮件服务器的信息包括:完整的登陆帐,登录密码。如果不添加的,就采用系统默认的邮件地址发送外网邮件。发送外网邮件时,可以让用户输入外网邮件发送地址,主题,内容,就可以直接发送外网邮件。如下图所示:

图3.17 设置代理邮箱地址界面

图3.18  发送外网邮件界面

主要代码

MailSenderInfomailInfo = new MailSenderInfo();

String[] temp=from.split("@");

StringBuffer buffer=new StringBuffer();

String before="smtp.";

String result=buffer.append(before).append(temp[1]).toString();

mailInfo.setMailServerHost(result);

mailInfo.setMailServerPort("25");

mailInfo.setValidate(true);

mailInfo.setUserName(from);

mailInfo.setPassword(password);//您的邮箱密码

mailInfo.setFromAddress(from);

mailInfo.setToAddress(to);

mailInfo.setSubject(subject);

mailInfo.setContent(content);

//这个类主要来发送邮件

SimpleMailSender sms = new SimpleMailSender();

sms.sendTextMail(mailInfo);//发送文体格式

4、 实现数字签名作用到邮件收发系统;

4.

4.1.   邮件中数据传输的几个安全性需求

1. 数据的保密性:用于防止非法用户进入系统及合法用户对系统资源的非法使用;通过对一些敏感的数据文件进行加密来保护系统之间的数据交换,防止除接收方之外的第三方截获数据及即使获取文件也无法得到其内容。

  2. 数据的完整性:防止非法用户对进行交换的数据进行无意或恶意的修改、插入,防止交换的数据丢失等。

  3. 数据的不可否认性:对数据和信息的来源进行验证,以确保数据由合法的用户发出;防止数据发送方在发出数据后又加以否认;同时防止接收方在收到数据后又否认曾收到过此数据及篡改数据。

4.2.    在邮件系统中实现数字签名

  使用公钥与私钥的目的就是实现安全的电子邮件,必须实现如下目的:

  1.我发送给你的内容必须加密,在邮件的传输过程中不能被别人看到。

  2.必须保证是我发送的邮件,不是别人冒充我的。

  要达到这样的目标必须发送邮件的两人都有公钥和私钥。

  公钥,就是给大家用的,你可以通过电子邮件发布,可以通过网站让别人下载,公钥其实是用来加密/验章用的。私钥,就是自己的,必须非常小心保 存,最好加上密码,私钥是用来解密/签章,首先就Key的所有权来说,私钥只有个人拥有。公钥与私钥的作用是:用公钥加密的内容只能用私钥解密,用私钥加 密的内容只能用公钥解密。

  比如说,我要给你发送一个加密的邮件。首先,我必须拥有你的公钥,你也必须拥有我的公钥。

  首先,我用你的公钥给这个邮件加密,这样就保证这个邮件不被别人看到,而且保证这个邮件在传送过程中没有被修改。你收到邮件后,用你的私钥就可以解密,就能看到内容。

  其次我用我的私钥给这个邮件加密,发送到你手里后,你可以用我的公钥解密。因为私钥只有我手里有,这样就保证了这个邮件是我发送的。

  当A->B资料时,A会使用B的公钥加密,这样才能确保只有B能解开,否则普罗大众都能解开加密的讯息,就是去了资料的保密性。验证方面 则是使用签验章的机制,A传资料给大家时,会以自己的私钥做签章,如此所有收到讯息的人都可以用A的公钥进行验章,便可确认讯息是由A发出来的了。

4.3.    Java中实现数字签名

运用java.security类中现成的MD5和RSA算法,JAVA的数字签名类封装在Signature类中。编写三个功能:
       1、生成一对密钥,即私钥和公钥,对于密钥的保存可以使用对象流的方式进行保存和传送,也可以使用编码的方式保存;在这里基于方便,我是使用编码方式进行保存的,这里的公钥和私钥是用户注册时系统按UUID算法自动分配产生的,然后保存在用户表中,要使用时再拿出来;
    2、编写发送者的功能:首先通过私钥加密待输出数据Data,并输出Data和签名后的Data(即摘要);        
    3、编写接收者的功能:使用发送者的公钥来验证发送过来的Data和摘要,判断签名的合法性;

代码实现:

public List<String> getKey(String infor) {

List<String> list = new ArrayList<String>();

try {

byte[]info = infor.getBytes();

// 产生RSA密钥对(myKeyPair)

KeyPairGenerator myKeyGen =KeyPairGenerator.getInstance("RSA");

myKeyGen.initialize(1024);

KeyPair myKeyPair =myKeyGen.generateKeyPair();

System.out.println("得到RSA密钥对");

// 转换

KeyPair keys = myKeyPair;

PublicKey publickey = keys.getPublic();//获得生成的公钥

PrivateKey privatekey =keys.getPrivate();//获得生成的私钥

String pubkey = StringAndByte.bytesToHexStr(publickey

.getEncoded());// 把公钥转化成String型

String prikey = StringAndByte.bytesToHexStr(privatekey

.getEncoded());// 把私钥转化成String型

list.add(pubkey);

list.add(prikey);

// 把一个消息进行签名并返回签名后的消息

public String signature(String infor, String prikey)throws Exception {

String sigResults=null;

byte[] info = infor.getBytes();

Signature mySig = Signature.getInstance("SHA1WithRSA");// 用指定算法产生签名对象

byte[] pubk = StringAndByte.hexStrToBytes(prikey);//将私钥转化成十六进制

PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(pubk);

KeyFactory keyf = null;

keyf = KeyFactory.getInstance("RSA");

PrivateKey mypubkey = null;

mypubkey =keyf.generatePrivate(priPKCS8);

mySig.initSign(mypubkey); // 用私钥初始化签名对象

mySig.update(info); // 将待签名的数据传送给签名对象(须在初始化之后)

byte[] sigResult = mySig.sign();// 返回签名结果字节数组

sigResults=StringAndByte.bytesToHexStr(sigResult);

returnsigResults;

//这个是用来验证消息和摘要是否一样

public boolean check(String infor, String sigResults, String pubkey)

throws Exception {

byte[] info = infor.getBytes();

Signature mySig = Signature.getInstance("SHA1WithRSA");// 用指定算法产生签名对象

byte[] pubk = StringAndByte.hexStrToBytes(pubkey);//将公钥转化成十六进制

X509EncodedKeySpec priPKCS8=new X509EncodedKeySpec(pubk);

KeyFactory keyf = null;

keyf = KeyFactory.getInstance("RSA");

PublicKey mypubkey = null;

mypubkey = keyf.generatePublic(priPKCS8);

byte[] sigResultb=StringAndByte.hexStrToBytes(sigResults);

// 用公钥验证签名结果

mySig.initVerify(mypubkey); //使用公钥初始化签名对象,用于验证签名

mySig.update(info); // 更新签名内容

boolean verify = mySig.verify(sigResultb);// 得到验证结果

return verify;

4.4.    对邮件进行数字签名

从用户的数据库中取出用户的公钥和私钥。将公钥和使用私钥签名后生成的文摘发送到服务器,然后保存到数据库。具体实现代码如下:

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);

4.5.收件人对邮件内容的验证

收件人收到发来签名后的摘要以及邮件原始内容,然后从数据库中取出发件人的公钥,对邮件进行验证,如果验证的结果和摘要的一样,则“显示数字签名正确”,否则显示“邮件已破坏”。具体实现代码如下:

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 {      %>

此邮件已破坏。

<%         }                %>

结论

本文以技术实现过程为基础设计和实现了一个基于java带数字签名的邮件收发系统,详细讨论了基于java带数字签名的邮件收发系统的具体实现,整个系统在本地Myeclipse8.6+MySQL5.0环境下运行,实现预期的功能。

1、它具有如下优点:

(1)实用性

本系统可以实现邮件收发功能。用户只要在本系统注册,填入相关的信息,成功注册为本系统用户后,再次输入正确的用户名和密码,登陆系统,进入系统主界面,就可以发送邮件,或者读取邮件。

(2)安全性

本系统在实现邮件收发功能的同时,还对邮件内容进行数字签名,将系统生成的签名摘要,发送至服务器端,在服务器端,把接收到的邮件信息,经过接收到的公钥加密生成的另一摘要,将接收到的摘要和此生成摘要进行比较,如果相等,则说明此邮件是没有被破坏的。这样就可以实现发送方的不可抵赖性,本系统的优势正在于此。此外,本系统还对用户的密码以及其他的敏感信息使用MD5进行压缩保存,从而更加完善地保护用户的信息。

(3)简洁性

本系统操作使用方便,界面简洁。此系统的功能界面是模拟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带数字签名的邮件收发系统相关推荐

  1. 基于java的数字签名技术在电子政务中的应用

    肖蕾    杨世平      摘要  本文介绍了数字签名技术在电子政务中的应用,传统的数字签名技术都是基于非对称的密码算法,原文以明文的方式传送,在这种方式下,原文的安全性受到了极大的威胁,因此,本文 ...

  2. 基于JAVA高校实习管理平台系统计算机毕业设计源码+数据库+lw文档+系统+部署

    基于JAVA高校实习管理平台系统计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA高校实习管理平台系统计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S架构 ...

  3. 基于Java毕业设计学生用品采购系统源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计学生用品采购系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计学生用品采购系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开 ...

  4. 基于Java毕业设计医院门诊分诊系统源码+系统+mysql+lw文档+部署软件

    基于Java毕业设计医院门诊分诊系统源码+系统+mysql+lw文档+部署软件 基于Java毕业设计医院门诊分诊系统源码+系统+mysql+lw文档+部署软件 本源码技术栈: 项目架构:B/S架构 开 ...

  5. dispatch作用 react_「React系列」手把手带你撸后台系统(Redux与路由鉴权)

    [React系列]手把手带你撸后台系统(Redux与路由鉴权) 来源:https://juejin.im/post/5d9b5ddee51d45781b63b8f7 上一篇我们介绍了系统架构,这一篇将 ...

  6. 基于Java的设计开题报告_基于Java的电子邮件的收发系统的设计与实现开题报告...

    基于Java的电子邮件的收发系统的设计与实现开题报告 (8页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.90 积分 开题报告 基于 Java 的电子 ...

  7. java中ssm付款代码_基于Java+SSM的网上订餐系统、基于JavaWeb的网上订餐系统

    需求分析 基于Java+SSM框架实现一个校园点餐系统,包括用户端和管理员端; 前台主要功能有用户注册, 用户登录, 我的购物车.我的订单.商品评论.校园资讯等; 管理员端主要功能有:用户管理.商品管 ...

  8. 基于JAVA高铁在线购票系统计算机毕业设计源码+数据库+lw文档+系统+部署

    基于JAVA高铁在线购票系统计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA高铁在线购票系统计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S架构 开发语 ...

  9. 基于JAVA工作流流程编辑OA系统计算机毕业设计源码+数据库+lw文档+系统+部署

    基于JAVA工作流流程编辑OA系统计算机毕业设计源码+数据库+lw文档+系统+部署 基于JAVA工作流流程编辑OA系统计算机毕业设计源码+数据库+lw文档+系统+部署 本源码技术栈: 项目架构:B/S ...

最新文章

  1. 安装Rabbitmq脚本
  2. struts2 Action 通过Spring管理, 并通过Spring的方式读取配置文件
  3. html调整文字位在基线显示,html – 将标题对齐到相同的基线,无论后续文字是什么?...
  4. 股东痛斥联想管理层:都是帅哥 但业绩差
  5. Visual Studio 2008 每日提示(一)
  6. 计算机网络上机指导,计算机网络上机指导书.pdf
  7. CSND Markdown模板
  8. 月入30K 的电子工程师很常见吗,需要具备啥素质才配得上这个薪资
  9. 大工《画法几何与机械制图》课程设计大作业离线作业
  10. 网易蜗牛读书与微信读书竞品分析
  11. KYLO的JVM知识总结
  12. 英文单词之说文解字(9)
  13. [UE4]大型户外场景制作教程
  14. 【嵌入式】CPU性能提升:流水线机制
  15. IE浏览器下载文本文件(txt,csv等)
  16. C51接入OneNET-实现数据上传和命令下发
  17. 锁相环PLL的工作原理
  18. H5游戏开发很重要,后台可控可测,超圣刷流水,招代理稳赢
  19. C#关键字之internal详解
  20. 【Java案例】为新员工分配部门

热门文章

  1. kivy中文问题解决
  2. 在线花店php,网上花店 php
  3. 模仿小米安全中心检测效果(进度条效果)
  4. 【SMS】SMS协议介绍之短消息中心(SC)
  5. 清除sys.aud$
  6. 为什么核弹爆炸会形成蘑菇云?
  7. 使用Python,OpenCV制作全透明的logo水印,对图像添加水印
  8. android.view.InflateException: Binary XML file line(报错日志要从下往上看)
  9. 学计算机20天培训心得体会学生,课件制作培训心得体会(精选11篇)
  10. 三分钟读完《人人都是产品经理》