数字签名课程设计_各种形式的数字签名

2020-02-28 其他范文 下载本文

数字签名课程设计由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“各种形式的数字签名”。

数字签名的目的和意义

RSA公开密钥加密算法自20世纪70年代提出以来,已经得到了广泛认可和应用。发展至今,电子安全领域的各方面已经形成了较为完备的国际规范。RSA作为最重要的公开密钥算法,在各领域的应用数不胜数。RSA在硬件方面,以技术成熟的IC应用于各种消费类电子产品。

RSA在软件方面的应用,主要集中在Internet上。加密连接、数字签名和数字证书的核心算法广泛使用RSA。日常应用中,有比较著名的工具包Open SSL(SSL,Security Socket Layer,是一个安全传输协议,在Internet上进行数据保护和身份确认。Open SSL是一个开放源代码的实现了SSL及相关加密技术的软件包,由加拿大的Eric Yang等发起编写的。Open SSL应用RSA实现签名和密钥交换,已经在各种操作系统得到非常广泛的应用。另外,家喻户晓的IE浏览器,自然也实现了SSL协议,集成了使用RSA技术的加密功能,结合MD5和SHA1,主要用于数字证书和数字签名,对于习惯于使用网上购物和网上银行的用户来说,几乎天天都在使用RSA技术。

RSA更出现在要求高度安全稳定的企业级商务应用中。在当今的企业级商务应用中,不得不提及使用最广泛的平台j2ee。事实上,在j2se的标准库中,就为安全和加密服务提供了两组API:JCA和JCE。JCA(Java Cryptography Architecture)提供基本的加密框架,如证书、数字签名、报文摘要和密钥对产生器; JCA由几个实现了基本的加密技术功能的类和接口组成,其中最主要的是java.security包,此软件包包含的是一组核心的类和接口,Java中数字签名的方法就集中在此软件包中。JCE(Java Cryptography Extension)在JCA的基础上作了扩展,JCE也是由几个软件包组成,其中最主要的是javax.crypto包,此软件包提供了JCE加密技术操作API。javax.crypto中的Cipher类用于具体的加密和解密。在上述软件包的实现中,集成了应用RSA算法的各种数据加密规范(RSA算法应用规范介绍参见: http://www.daodoc.com/rsalabs/node.asp?id=2146,这些API内部支持的算法不仅仅只有RSA,但是RSA是数字签名和证书中最常用的),用户程序可以直接使用java标准库中提供的API进行数字签名和证书的各种操作。

2.数字签名算法的基本框架 1.密钥的产生

①选择两个保密的大素数P和q。②计算N=p q,≯(N)=(p-1)(g-1),其中≯(N)是N的欧拉函数值。③选择一个整数e,满足l

⑤以(e, n)为公钥,(d ,N)为密钥,销毁p,q,≯(N)。2.加密

加密时首先将明文比特串进行分组,使得每个分组对应得串在数值上小于N,即分组的二进制长度小于l092N。然后,对每个明文分组M,作加密运算:

C=E k(M)=M e mod N 3.解密

对密文分组的解密运算为: M=D k(C)=C d mod N

由定理1和定理2可以证明解密运算能恢复明文M

并非所有的公开密钥系统,均可同时达到秘密性与数字签名功能。一般而言,一公开密钥系统若作为密码系统,则无法作为数字签名,反之亦然。只有很少数的系统可同时作为密码系统和数字签名,如本文讨论的RSA系统。RSA签名算 法如下:

设N=p q,且p和q是两个大素数,e和d满足e d≡l(mod ≯(N))。公开密钥:N,e 私有密钥:d

签名过程:发送方使用自己的私钥d对明文m进行数字签名变换: y=x d mod N:并将加密后的消息和签名y发送给接收方;

验证过程:接收方使用发送方的公钥e对收到的消息y进行数字签名验证变换x’=ye mod N,并使用发送方的密钥解密恢复消息x,比较x’与x,如果x’=x则证实发送方的身份合法。

这样,用户A若想用RSA签名方案对消息x签名,他只需公开他的公钥N和e,由于签名算法是保密的,因此A是唯一能产生签名的人,任何要验证用户A 签名的用户只需查到A的公钥即可验证签名。对于实现签名和公钥加密的组合,常用方法是:假定通信双方为A和B。对于明文x,A计算他的签名y=x d mod N,然后利用B的公开加密函数EB对信息对(x, y)加密得到Z,将密文Z传送给B,当B收到密文Z后,他首先用他的解密函数DB来解密得到(x,y)=DB(Z)= DB(EB(x,y)),然后利用A的验证算法来检查x’=x=y e mod N是否成立。

3.主要模块的算法以及关键代码

①.文件选择模块的主要算法及关键代码 CfileDialog dlg(TRUE,NULL,“.签名的文件”,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL);if(dlg.DoModal()==IDOK){

m_file_sign=dlg.GetPathName();} else m_file_sign=“”;UpdateData(FALSE);②.保存公钥的文件路径的主要算法及关键代码 CFileDialog dlg(FALSE,NULL,“.公钥”,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL);if(dlg.DoModal()==IDOK){

m_pkey_sign=dlg.GetPathName();} else m_pkey_sign=“”;UpdateData(FALSE);③.保存签名后的文件的路径主要算法及关键代码

CFileDialog dlg(FALSE,NULL,“.签名后的文件”,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL);if(dlg.DoModal()==IDOK){

m_signed_sign=dlg.GetPathName();} else m_signed_sign=“”;UpdateData(FALSE);④.数字签名的主要算法及关键代码 HCRYPTPROV hProv;//秘钥容器句柄

BYTE *pbBuffer;//被签名的数据

HCRYPTHASH hHash;HCRYPTKEY hKey;BYTE *pbKeyBlob;

//签名者得公钥数据

BYTE *pbSignature;

//数字签名

DWORD dwSigLen;DWORD dwBlobLen;DWORD dwBufferLen;LPTSTR szDescription = “”;

CFile m_pubkey_file,m_sign_file,m_signdatafile;if(m_pkey_sign==“”||!m_pubkey_file.Open(m_pkey_sign,CFile::modeCreate|CFile::modeReadWrite)){

MeageBox(“请选择正确的保存公钥的文件路径”);return;} if(m_file_sign==“”||!m_signdatafile.Open(m_file_sign,CFile::modeReadWrite)){

MeageBox(“请选择正确的文件路径”);return;} if(m_signed_sign==“”||!m_sign_file.Open(m_signed_sign,CFile::modeCreate|CFile::modeReadWrite)){

MeageBox(“请选择正确保存数字签名的文件路径”);return;} UpdateData(TRUE);m_state_sign=“”;//获取缺省的秘钥容器

if(CryptAcquireContext(&hProv,NULL,NULL,m_prov_sign,0)){

m_state_sign+=“已获取CSP上下文,秘钥生成算法:”+GetProvType(m_prov_sign)+“n”;} else

//密钥容器不存在创建之

{

if(CryptAcquireContext(&hProv,NULL,NULL,m_prov_sign,CRYPT_NEWKEYSET))

m_state_sign+=“已创建一个新的密钥容器,秘钥生成算法:”+GetProvType(m_prov_sign)+“n”;

else

{ m_state_sign+=MyHandleError(“在获取CSP时发生错误,程序停止.”);UpdateData(FALSE);return;} } // 从密钥容器中取数字签名用的密钥

if(CryptGetUserKey(hProv,AT_SIGNATURE,&hKey))

m_state_sign+=“签名密钥已经获取.n”;else {

if(GetLastError()== NTE_NO_KEY)//密钥容器里不存在signature key pair创建之

{

if(CryptGenKey(hProv,//CSP句柄

AT_SIGNATURE, //创建的密钥对类型为signature key pair

0, //key类型,这里用默认值

&hKey))

//创建成功返回新创建的密钥对的句柄

m_state_sign+=“创建一个秘钥对n”;

else

{ m_state_sign+=MyHandleError(“在创建签名密钥对时发生错误,程序停止.n”);UpdateData(FALSE);return;}

}

else

{

m_state_sign+=MyHandleError(“在获取签名密钥时发生错误,程序停止.”);UpdateData(FALSE);return;

} } // 因为接收消息者要验证数字签名,所以要导出公钥给接收者。

if(CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,NULL,&dwBlobLen))//得到公钥的大小

m_state_sign+=“已获取公钥的大小,”;else { m_state_sign+=MyHandleError(“计算公钥大小时发生错误,程序停止.”);UpdateData(FALSE);return;} // 为存储公钥的缓冲区分配内存。

if((pbKeyBlob =(BYTE*)malloc(dwBlobLen)))

m_state_sign+=“已为公钥分配内存n”;else { m_state_sign+=MyHandleError(“为公钥分配内存时出现异常,退出.n”);UpdateData(FALSE);return;} // 真正导出公钥数据

if(CryptExportKey(hKey,NULL,PUBLICKEYBLOB,0,pbKeyBlob,//公钥

这个数据可以存入文件,发送给接收者。一般被存入数字证书

&dwBlobLen)){

m_pubkey_file.Write(pbKeyBlob,dwBlobLen);

m_state_sign+=“已导出公钥,存储在”+m_pubkey_file.GetFilePath()+“n”;} else {

m_state_sign+=MyHandleError(“导出公钥时发生错误,退出”);UpdateData(FALSE);return;} // 创建hash对象

if(CryptCreateHash(hProv,m_hash_sign,//CALG_MD5,0,0,&hHash)){

m_state_sign+=“已创建hash对象,加密算法”+GetHashType(m_hash_sign)+“nn”;} else { m_state_sign+=MyHandleError(“在创建hash对象时发生错误,退出”);UpdateData(FALSE);return;}

//把签名的数据读入内存

//分配空间

if((pbBuffer=(BYTE *)malloc(m_signdatafile.GetLength())))

m_state_sign+=“已经为数据”+m_signdatafile.GetFilePath()+“分配空间nn”;else {

m_state_sign+=MyHandleError(“为数据分配内存时发生异常,退出”);UpdateData(FALSE);return;} if(m_signdatafile.Read(pbBuffer,m_signdatafile.GetLength()))//把数据读入内存

m_state_sign+=“数据已经读入内存!”;else {m_state_sign+=MyHandleError(“数据读入内存发生错误,退出”);UpdateData(FALSE);return;} dwBufferLen = m_signdatafile.GetLength();// 对数据进行hash运算

if(CryptHashData(hHash,pbBuffer,dwBufferLen,0))

m_state_sign+=“已对数据进行hash运算n”;else { m_state_sign+=MyHandleError(“在对数据进行hash运算时发生错误,退出.”);UpdateData(FALSE);return;} // 使用signature key pair的私钥对hash数据签名

dwSigLen= 0;if(CryptSignHash(hHash,AT_SIGNATURE,szDescription,0,NULL,&dwSigLen))//得到数字签名大小

m_state_sign+=“已获取数字签名的大小,”;else { m_state_sign+=MyHandleError(“计算数字签名大小时发生错误,退出.”);UpdateData(FALSE);return;} // 为数字签名缓冲区分配内存

if((pbSignature =(BYTE *)malloc(dwSigLen)))

m_state_sign+=“已为数字签名分配缓冲n”;else { m_state_sign+=MyHandleError(“为数字签名分配内存时异常,退出.”);UpdateData(FALSE);return;} // 得到数字签名

if(CryptSignHash(hHash,AT_SIGNATURE,szDescription,0,pbSignature, //这里将返回数字签名,同被签名的数据一起发送给接收方

&dwSigLen))

{

m_sign_file.Write(pbSignature,dwSigLen);

m_state_sign+=“已导出数字签名,存储在”+m_sign_file.GetFilePath()+“nn”;} else {

m_state_sign+=MyHandleError(“导出数字签名时发生异常,退出.”);UpdateData(FALSE);return;} // 销毁hash对象.if(hHash){

CryptDestroyHash(hHash);

m_state_sign+=“销毁hash对象nn”;} m_state_sign+=“数字签名成功nn”;//关闭文件

m_pubkey_file.Close(),m_sign_file.Close(),m_signdatafile.Close(MeageBox(“数字签名成功!”,“”,MB_OK);UpdateData(FALSE);⑤.数字签名认证的主要算法及关键代码

HCRYPTPROV hProv;HCRYPTKEY hPubKey;BYTE *pbKeyBlob;DWORD dwBlobLen;HCRYPTHASH hHash;BYTE *pbSignature;

//数字签名

DWORD dwSigLen;LPTSTR szDescription = “”;UpdateData(TRUE);m_state_veri=“”;// 获得CSP句柄,密钥容器名为登陆用户名

if(CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,0)){

m_state_veri+=“已获取CSP,秘钥生成算法:);”+GetProvType(m_prov_veri)+“n”;} else

//密钥容器不存在创建之

{

if(CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_NEWKEYSET))

m_state_veri+=“已创建一个新的密钥容器秘钥生成算法:”+GetProvType(m_prov_veri)+“n”;

else

{ m_state_veri+=MyHandleError2(“在获取密钥容器时发生错误,退出n”);UpdateData(FALSE);return;} } CFile signdatafile,yuanwenfile,pubkeyfile;if(m_pkey_veri==“”||!pubkeyfile.Open(m_pkey_veri,CFile::modeReadWrite)){

MeageBox(“请选择正确的公钥文件!”);return;} if(m_file_veri==“”||!yuanwenfile.Open(m_file_veri,CFile::modeReadWrite)){

MeageBox(“请选择正确的原文件!”);return;}

if(m_signed_veri==“”||!signdatafile.Open(m_signed_veri,CFile::modeReadWrite)){

MeageBox(“请选择正确的签名文件!”);return;} dwBlobLen=pubkeyfile.GetLength();pbKeyBlob=(BYTE *)malloc(dwBlobLen);pubkeyfile.Read(pbKeyBlob,dwBlobLen);if(CryptImportKey(hProv,pbKeyBlob,dwBlobLen,0,0,&hPubKey))

m_state_veri+=“公钥已经成功导入!nn”;else {

m_state_veri+=MyHandleError2(“公钥导出出错.n”);UpdateData(FALSE);return;} // 创建哈希对象

if(CryptCreateHash(hProv,m_hash_veri,//CALG_MD5,0,0,&hHash))

m_state_veri+=“已经获取hash对象,hash算法”+GetHashType(m_hash_veri)+“nn”;else {

m_state_veri+=MyHandleError2(“创建hash对象时出错,退出”);UpdateData(FALSE);return;} // 跟生成时一样对数据进行hash运算

BYTE *pbBuffer;pbBuffer=(BYTE *)malloc(yuanwenfile.GetLength());yuanwenfile.Read(pbBuffer,yuanwenfile.GetLength());DWORD dwBufferLen = yuanwenfile.GetLength();pbSignature=(BYTE *)malloc(signdatafile.GetLength());signdatafile.Read(pbSignature,signdatafile.GetLength());dwSigLen = signdatafile.GetLength();if(CryptHashData(hHash,pbBuffer,dwBufferLen,0))

m_state_veri+=“对数据hash运算成功!nn”;else {

m_state_veri+=MyHandleError2(“对数据进行hash运算出错,退出”);UpdateData(FALSE);return;} // 验证数字签名

if(CryptVerifySignature(hHash,pbSignature, //数字签名数据

dwSigLen,hPubKey, //签名者的公钥

szDescription,0))

{

MeageBox(“恭喜:是正确的数字签名!”);

m_state_veri+=“恭喜:是正确的数字签名!”;} else {

MeageBox(“错误:签名是错误的n”);

m_state_veri+=“错误:签名是错误的n请检查参数是否设置正确,若正确则请联系发送方”;} UpdateData(FALSE);//------

// Free memory to be used to store signature.if(pbSignature)free(pbSignature);if(pbKeyBlob)free(pbKeyBlob);// Destroy the hash object.if(hHash)

CryptDestroyHash(hHash);// Release the provider handle.if(hProv)

CryptReleaseContext(hProv, 0);signdatafile.Close(),yuanwenfile.Close(),pubkeyfile.Close();4.RSA数字签名算法运行情况:

4.1 主界面初始化

4.2 签名界面

4.3 设置密钥

4.4 选择签名文件

4.5 选择保存公钥位置

4.6 选择选择签名后保存位置

4.6 进行数字签名结果

4.7 进行数字签名认证

4.8 进行数字签名认证结果

5.总结与展望:

通过本次对RSA算法的学习,明白了该算法加密解密的原理,以及他的安全性问题和缺点,通过这几周的实验,在学习中累计经验解决问题,让我对RSA算法有了较通透的理解,受益匪浅。随着Internet的发展,实现电子商务是未来的潮流和趋势,基于Internet开放环境下的信息安全将越来越受到重视,而RSA算法在身份认证,数字签名,信息加密等方面得到非常广泛的应用,对它作深入的了解是很有必要的。虽然RSA算法可靠性较高,但是还是有一些缺陷,就是运算量太大,速度太慢,适合加密比较短的明文。RSA方法既可用于保密,也可用于签名和认证,目前已经广泛应用与各种产品,平台等软件上。许多流行的操作系统上如微软,Apple,Sun和Novell都是在其产品上融入RSA。在硬件上,如安全电话,以太网和智能卡都使用了RSA技术。而且几乎所有Internet安全协议如S/MIME,SSL和S/WAN都引入了RSA加密方法。ISO9796标准把RSA列为一种兼容的加密算法。可以预见,在不远的几年内,RSA的 应用将来会越来越广泛。

《数字签名课程设计.docx》
将本文的Word文档下载,方便收藏和打印
推荐度:
数字签名课程设计
点击下载文档
相关专题 各种形式的数字签名 数字签名 课程设计 各种形式的数字签名 数字签名 课程设计
[其他范文]相关推荐
    [其他范文]热门文章
      下载全文