您好,欢迎访问三七文档
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算法应用规范介绍参见:=2146,这些API内部支持的算法不仅仅只有RSA,但是RSA是数字签名和证书中最常用的),用户程序可以直接使用java标准库中提供的API进行数字签名和证书的各种操作。2.数字签名算法的基本框架1.密钥的产生①选择两个保密的大素数P和q。②计算N=pq,≯(N)=(p-1)(g-1),其中≯(N)是N的欧拉函数值。③选择一个整数e,满足le≯(N),且gcd(≯(N),e)≡1。④计算私钥d(解密密钥),满足ed≡l(mod≯(N)),d是e在模≯(N)下的乘法逆元。⑤以(e,n)为公钥,(d,N)为密钥,销毁p,q,≯(N)。2.加密加密时首先将明文比特串进行分组,使得每个分组对应得串在数值上小于N,即分组的二进制长度小于l092N。然后,对每个明文分组M,作加密运算:C=Ek(M)=MemodN3.解密对密文分组的解密运算为: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,//创建的密钥对类型为signaturekeypair0,//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
本文标题:数字签名课程设计
链接地址:https://www.777doc.com/doc-7385437 .html