数字签名课程设计.docx
- 文档编号:30422014
- 上传时间:2023-08-14
- 格式:DOCX
- 页数:22
- 大小:145.07KB
数字签名课程设计.docx
《数字签名课程设计.docx》由会员分享,可在线阅读,更多相关《数字签名课程设计.docx(22页珍藏版)》请在冰豆网上搜索。
数字签名课程设计
数字签名课程设计
1.RSA数字签名的目的和意义
RSA公开密钥加密算法自20世纪70年代提出以来,已经得到了广泛认可和应用。
发展至今,电子安全领域的各方面已经形成了较为完备的国际规范。
RSA作为最重要的公开密钥算法,在各领域的应用数不胜数。
RSA在硬件方面,以技术成熟的IC应用于各种消费类电子产品。
RSA在软件方面的应用,主要集中在Internet上。
加密连接、数字签名和数字证书的核心算法广泛使用RSA。
日常应用中,有比较著名的工具包OpenSSL(SSL,SecuritySocketLayer,是一个安全传输协议,在Internet上进行数据保护和身份确认。
OpenSSL是一个开放源代码的实现了SSL及相关加密技术的软件包,由加拿大的EricYang等发起编写的。
OpenSSL应用RSA实现签名和密钥交换,已经在各种操作系统得到非常广泛的应用。
另外,家喻户晓的IE浏览器,自然也实现了SSL协议,集成了使用RSA技术的加密功能,结合MD5和SHA1,主要用于数字证书和数字签名,对于习惯于使用网上购物和网上银行的用户来说,几乎天天都在使用RSA技术。
RSA更出现在要求高度安全稳定的企业级商务应用中。
在当今的企业级商务应用中,不得不提及使用最广泛的平台j2ee。
事实上,在j2se的标准库中,就为安全和加密服务提供了两组API:
JCA和JCE。
JCA(JavaCryptographyArchitecture)提供基本的加密框架,如证书、数字签名、报文摘要和密钥对产生器;JCA由几个实现了基本的加密技术功能的类和接口组成,其中最主要的是java.security包,此软件包包含的是一组核心的类和接口,Java中数字签名的方法就集中在此软件包中。
JCE(JavaCryptographyExtension)在JCA的基础上作了扩展,JCE也是由几个软件包组成,其中最主要的是javax.crypto包,此软件包提供了JCE加密技术操作API。
javax.crypto中的Cipher类用于具体的加密和解密。
在上述软件包的实现中,集成了应用RSA算法的各种数据加密规范(RSA算法应用规范介绍参见:
,这些API内部支持的算法不仅仅只有RSA,但是RSA是数字签名和证书中最常用的),用户程序可以直接使用java标准库中提供的API进行数字签名和证书的各种操作。
2.数字签名算法的基本框架
1.密钥的产生
①选择两个保密的大素数P和q。
②计算N=pq,≯(N)=(p-1)(g-1),其中≯(N)是N的欧拉函数值。
③选择一个整数e,满足l ④计算私钥d(解密密钥),满足ed≡l(mod≯(N)),d是e在模≯(N)下的乘法逆元。 ⑤以(e,n)为公钥,(d,N)为密钥,销毁p,q,≯(N)。 2.加密 加密时首先将明文比特串进行分组,使得每个分组对应得串在数值上小于N,即分组的二进制长度小于l092N。 然后,对每个明文分组M,作加密运算: C=Ek(M)=MemodN 3.解密 对密文分组的解密运算为: M=Dk(C)=CdmodN 由定理1和定理2可以证明解密运算能恢复明文M 并非所有的公开密钥系统,均可同时达到秘密性与数字签名功能。 一般而言,一公开密钥系统若作为密码系统,则无法作为数字签名,反之亦然。 只有很少数 的系统可同时作为密码系统和数字签名,如本文讨论的RSA系统。 RSA签名算 法如下: 设N=pq,且p和q是两个大素数,e和d满足ed≡l(mod≯(N))。 公开密钥: N,e 私有密钥: d 签名过程: 发送方使用自己的私钥d对明文m进行数字签名变换: y=xdmodN: 并将加密后的消息和签名y发送给接收方; 验证过程: 接收方使用发送方的公钥e对收到的消息y进行数字签名验证变换x’=yemodN,并使用发送方的密钥解密恢复消息x,比较x’与x,如果x’=x则证实发送方的身份合法。 这样,用户A若想用RSA签名方案对消息x签名,他只需公开他的公钥N和e,由于签名算法是保密的,因此A是唯一能产生签名的人,任何要验证用户A签名的用户只需查到A的公钥即可验证签名。 对于实现签名和公钥加密的组合,常用方法是: 假定通信双方为A和B。 对于明文x,A计算他的签名y=xdmodN,然后利用B的公开加密函数EB对信息对(x,y)加密得到Z,将密文Z传送给B,当B收到密文Z后,他首先用他的解密函数DB来解密得到(x,y)=DB(Z)=DB(EB(x,y)),然后利用A的验证算法来检查x’=x=yemodN是否成立。 3.主要模块的算法以及关键代码 ①.文件选择模块的主要算法及关键代码 CfileDialogdlg(TRUE,NULL,".\\签名的文件",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL); if(dlg.DoModal()==IDOK) { m_file_sign=dlg.GetPathName(); } elsem_file_sign=""; UpdateData(FALSE); ②.保存公钥的文件路径的主要算法及关键代码 CFileDialogdlg(FALSE,NULL,".\\公钥",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL); if(dlg.DoModal()==IDOK) { m_pkey_sign=dlg.GetPathName(); } elsem_pkey_sign=""; UpdateData(FALSE); ③.保存签名后的文件的路径主要算法及关键代码 CFileDialogdlg(FALSE,NULL,".\\签名后的文件",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,NULL,NULL); if(dlg.DoModal()==IDOK) { m_signed_sign=dlg.GetPathName(); } elsem_signed_sign=""; UpdateData(FALSE); ④.数字签名的主要算法及关键代码 HCRYPTPROVhProv;//秘钥容器句柄 BYTE*pbBuffer;//被签名的数据 HCRYPTHASHhHash; HCRYPTKEYhKey; BYTE*pbKeyBlob;//签名者得公钥数据 BYTE*pbSignature;//数字签名 DWORDdwSigLen; DWORDdwBlobLen; DWORDdwBufferLen; LPTSTRszDescription=""; CFilem_pubkey_file,m_sign_file,m_signdatafile; if(m_pkey_sign==""||! m_pubkey_file.Open(m_pkey_sign,CFile: : modeCreate|CFile: : modeReadWrite)) { MessageBox("请选择正确的保存公钥的文件路径");return; } if(m_file_sign==""||! m_signdatafile.Open(m_file_sign,CFile: : modeReadWrite)) { MessageBox("请选择正确的文件路径");return; } if(m_signed_sign==""||! m_sign_file.Open(m_signed_sign,CFile: : modeCreate|CFile: : modeReadWrite)) { MessageBox("请选择正确保存数字签名的文件路径");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)//密钥容器里不存在signaturekeypair创建之 { if(CryptGenKey( hProv,//CSP句柄 AT_SIGNATURE,//创建的密钥对类型为signaturekeypair 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)+"\n\n"; } else {m_state_sign+=MyHandleError("在创建hash对象时发生错误,退出");UpdateData(FALSE);return;} //把签名的数据读入内存 //分配空间 if((pbBuffer=(BYTE*)malloc(m_signdatafile.GetLength()))) m_state_sign+="已经为数据"+m_signdatafile.GetFilePath()+"分配空间\n\n"; 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;} //使用signaturekeypair的私钥对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()+"\n\n"; } else { m_state_sign+=MyHandleError("导出数字签名时发生异常,退出.");UpdateData(FALSE);return; } //销毁hash对象. if(hHash) { CryptDestroyHash(hHash); m_state_sign+="销毁hash对象\n\n"; } m_state_sign+="数字签名成功\n\n"; //关闭文件 m_pubkey_file.Close(),m_sign_file.Close(),m_signdatafile.Close(); MessageBox("数字签名成功! ","",MB_OK); UpdateData(FALSE); ⑤.数字签名认证的主要算法及关键代码 HCRYPTPROVhProv; HCRYPTKEYhPubKey; BYTE*pbKeyBlob; DWORDdwBlobLen; HCRYPTHASHhHash; BYTE*pbSignature;//数字签名 DWORDdwSigLen; LPTSTRszDescription=""; 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;} } CFilesigndatafile,yuanwenfile,pubkeyfile; if(m_pkey_veri==""||! pubkeyfile.Open(m_pkey_veri,CFile: : modeReadWrite)) { MessageBox("请选择正确的公钥文件! ");return; } if(m_file_veri==""||! yuanwenfile.Open(m_file_veri,CFile: : modeReadWrite)) { MessageBox("请选择正确的原文件! ");return; } if(m_signed_veri==""||! signdatafile.Open(m_signed_veri,CFile: : modeReadWrite)) { MessageBox("请选择正确的签名文件! ");return; } dwBlobLen=pubkeyfile.GetLength(); pbKeyBlob=(BYTE*)malloc(dwBlobLen); pubkeyfile.Read(pbKeyBlob,dwBlobLen); if(CryptImportKey( hProv, pbKeyBlob, dwBlobLen, 0, 0, &hPubKey)) m_state_veri+="公钥已经成功导入! \n\n"; 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)+"\n\n"; else { m_state_veri+=MyHandleError2("创建hash对象时出错,退出");UpdateData(FALSE);return; } //跟生成时一样对数据进行hash运算 BYTE*pbBuffer; pbBuffer=(BYTE*)malloc(yuanwenfile.GetLength()); yuanwenfile.Read(pbBuffer,yuanwenfile.GetLength()); DWORDdwBufferLen=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运算成功! \n\n"; else { m_state_veri+=MyHandleError2("对数据进行hash运算出错,退出");UpdateData(FALSE);return; } //验证数字签名 if(CryptVerifySignature( hHash, pbSignature,//数字签名数据 dwSigLen, hPubKey,//签名者的公钥 szDescription, 0)) { MessageBox("恭喜: 是正确的数字签名! "); m_state_veri+="恭喜: 是正确的数字签名! "; } else { MessageBox("错误: 签名是错误的\n"); m_state_veri+="错误: 签名是错误的\n请检查参数是否设置正确,若正确则请联系发送方"; } UpdateData(FALSE); //------------------------------------------------------
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数字签名 课程设计