《数字签名课程设计.doc》由会员分享,可在线阅读,更多相关《数字签名课程设计.doc(19页珍藏版)》请在三一办公上搜索。
1、精选优质文档-倾情为你奉上1.RSA数字签名的目的和意义RSA公开密钥加密算法自20世纪70年代提出以来,已经得到了广泛认可和应用。发展至今,电子安全领域的各方面已经形成了较为完备的国际规范。RSA作为最重要的公开密钥算法,在各领域的应用数不胜数。RSA在硬件方面,以技术成熟的IC应用于各种消费类电子产品。RSA在软件方面的应用,主要集中在Internet上。加密连接、数字签名和数字证书的核心算法广泛使用RSA。日常应用中,有比较著名的工具包Open SSL(SSL,Security Socket Layer,是一个安全传输协议,在Internet上进行数据保护和身份确认。Open SSL是一
2、个开放源代码的实现了SSL及相关加密技术的软件包,由加拿大的Eric Yang等发起编写的。Open SSL应用RSA实现签名和密钥交换,已经在各种操作系统得到非常广泛的应用。另外,家喻户晓的IE浏览器,自然也实现了SSL协议,集成了使用RSA技术的加密功能,结合MD5和SHA1,主要用于数字证书和数字签名,对于习惯于使用网上购物和网上银行的用户来说,几乎天天都在使用RSA技术。RSA更出现在要求高度安全稳定的企业级商务应用中。在当今的企业级商务应用中,不得不提及使用最广泛的平台j2ee。事实上,在j2se的标准库中,就为安全和加密服务提供了两组API:JCA和JCE。 JCA (Java C
3、ryptography Architecture)提供基本的加密框架,如证书、数字签名、报文摘要和密钥对产生器; JCA由几个实现了基本的加密技术功能的类和接口组成,其中最主要的是java.security包,此软件包包含的是一组核心的类和接口,Java中数字签名的方法就集中在此软件包中。JCE(Java Cryptography Extension) 在JCA的基础上作了扩展,JCE也是由几个软件包组成,其中最主要的是javax.crypto包,此软件包提供了JCE加密技术操作API。javax.crypto中的Cipher类用于具体的加密和解密。在上述软件包的实现中,集成了应用RSA算法的
4、各种数据加密规范(RSA算法应用规范介绍参见: ,这些API内部支持的算法不仅仅只有RSA,但是RSA是数字签名和证书中最常用的),用户程序可以直接使用java标准库中提供的API进行数字签名和证书的各种操作。2数字签名算法的基本框架1密钥的产生选择两个保密的大素数P和q。计算N=p q,(N) =(p-1)(g-1),其中(N)是N的欧拉函数值。选择一个整数e,满足le(N),且g c d(N),e)1。计算私钥d(解密密钥),满足e dl(mod(N),d是e在模(N)下的乘法逆元。 以(e, n)为公钥,(d ,N)为密钥,销毁p,q,(N)。2加密加密时首先将明文比特串进行分组,使得每
5、个分组对应得串在数值上小于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 dl(mod (N)。公开密钥:N,e 私有密钥:d 签名过程:发送
6、方使用自己的私钥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的公开加密函数E
7、B对信息对(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=;UpdateDat
8、a(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
9、(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
10、 = ; CFile m_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_fil
11、e.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, NUL
12、L, NULL, m_prov_sign, CRYPT_NEWKEYSET) m_state_sign+=已创建一个新的密钥容器,秘钥生成算法:+GetProvType(m_prov_sign)+n;elsem_state_sign+=MyHandleError(在获取CSP时发生错误,程序停止.);UpdateData(FALSE);return;/ 从密钥容器中取数字签名用的密钥if(CryptGetUserKey( hProv, AT_SIGNATURE, &hKey) m_state_sign+=签名密钥已经获取. n;elseif(GetLastError() = NTE_NO_KE
13、Y) /密钥容器里不存在signature key pair创建之if(CryptGenKey(hProv,/CSP句柄AT_SIGNATURE,/创建的密钥对类型为signature key pair0,/key类型,这里用默认值&hKey) /创建成功返回新创建的密钥对的句柄m_state_sign+=创建一个秘钥对n;elsem_state_sign+=MyHandleError(在创建签名密钥对时发生错误,程序停止.n); UpdateData(FALSE);return;elsem_state_sign+=MyHandleError(在获取签名密钥时发生错误,程序停止.);Updat
14、eData(FALSE);return;/ 因为接收消息者要验证数字签名,所以要导出公钥给接收者。if(CryptExportKey( hKey, NULL, PUBLICKEYBLOB,0, NULL, &dwBlobLen) /得到公钥的大小m_state_sign+=已获取公钥的大小,;elsem_state_sign+=MyHandleError(计算公钥大小时发生错误,程序停止.);UpdateData(FALSE);return;/ 为存储公钥的缓冲区分配内存。if(pbKeyBlob = (BYTE*)malloc(dwBlobLen) m_state_sign+=已为公钥分配内
15、存n;elsem_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;elsem_state_s
16、ign+=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;elsem_state_sign+=MyHandleError(在创建hash对象时发生错误,退出);UpdateData(FALSE);return;/把签名的数据读入内存/分配空间if(pbBuffer=(BYTE *)
17、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(数据读入内存发生错误,退出
18、);UpdateData(FALSE);return;dwBufferLen = m_signdatafile.GetLength();/ 对数据进行hash运算if(CryptHashData(hHash, pbBuffer, dwBufferLen, 0) m_state_sign+=已对数据进行hash运算n;elsem_state_sign+=MyHandleError(在对数据进行hash运算时发生错误,退出.);UpdateData(FALSE);return;/ 使用signature key pair的私钥对hash数据签名dwSigLen= 0;if(CryptSignHas
19、h(hHash, AT_SIGNATURE, szDescription, 0, NULL, &dwSigLen) /得到数字签名大小m_state_sign+=已获取数字签名的大小,;elsem_state_sign+=MyHandleError(计算数字签名大小时发生错误,退出.);UpdateData(FALSE);return;/ 为数字签名缓冲区分配内存if(pbSignature = (BYTE *)malloc(dwSigLen)m_state_sign+=已为数字签名分配缓冲n;elsem_state_sign+=MyHandleError(为数字签名分配内存时异常,退出.);
20、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;elsem_state_sign+=MyHandleError(导出数字签名时发生异常,退出.);UpdateData(FALSE)
21、;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();MessageBox(数字签名成功!,MB_OK);UpdateData(FALSE);数字签名认证的主要算法及关键代码HCRYPTPROV hProv;HCRYPTKEY hPubKey;BYTE *pbKeyBlob;DWORD dwBlobLen;HCR
22、YPTHASH 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
23、, PROV_RSA_FULL, CRYPT_NEWKEYSET) m_state_veri+=已创建一个新的密钥容器秘钥生成算法:+GetProvType(m_prov_veri)+n;elsem_state_veri+=MyHandleError2(在获取密钥容器时发生错误,退出n);UpdateData(FALSE);return;CFile signdatafile,yuanwenfile,pubkeyfile;if(m_pkey_veri=|!pubkeyfile.Open(m_pkey_veri,CFile:modeReadWrite)MessageBox(请选择正确的公钥文件!)
24、;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
25、,dwBlobLen);if(CryptImportKey(hProv,pbKeyBlob,dwBlobLen,0,0,&hPubKey)m_state_veri+=公钥已经成功导入!nn;elsem_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;elsem_
26、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();sign
27、datafile.Read(pbSignature,signdatafile.GetLength();dwSigLen = signdatafile.GetLength();if(CryptHashData(hHash, pbBuffer, dwBufferLen, 0) m_state_veri+=对数据hash运算成功!nn;elsem_state_veri+=MyHandleError2(对数据进行hash运算出错,退出);UpdateData(FALSE);return;/ 验证数字签名if(CryptVerifySignature(hHash, pbSignature,/数字签名数据
28、dwSigLen, hPubKey,/签名者的公钥szDescription, 0) MessageBox(恭喜:是正确的数字签名!);m_state_veri+=恭喜:是正确的数字签名!;elseMessageBox(错误:签名是错误的n);m_state_veri+=错误:签名是错误的n请检查参数是否设置正确,若正确则请联系发送方;UpdateData(FALSE);/-/ Free memory to be used to store signature.if(pbSignature)free(pbSignature);if(pbKeyBlob)free(pbKeyBlob);/ Des
29、troy 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 进行数字签名认
30、证结果5. 总结与展望:通过本次对RSA算法的学习,明白了该算法加密解密的原理,以及他的安全性问题和缺点,通过这几周的实验,在学习中累计经验解决问题,让我对RSA算法有了较通透的理解,受益匪浅。随着Internet的发展,实现电子商务是未来的潮流和趋势,基于Internet开放环境下的信息安全将越来越受到重视,而RSA算法在身份认证,数字签名,信息加密等方面得到非常广泛的应用,对它作深入的了解是很有必要的。虽然RSA算法可靠性较高,但是还是有一些缺陷,就是运算量太大,速度太慢,适合加密比较短的明文。RSA方法既可用于保密,也可用于签名和认证,目前已经广泛应用与各种产品,平台等软件上。许多流行的操作系统上如微软,Apple,Sun和Novell都是在其产品上融入RSA。在硬件上,如安全电话,以太网和智能卡都使用了RSA技术。而且几乎所有Internet安全协议如S/MIME,SSL和S/WAN都引入了RSA加密方法。ISO9796标准把RSA列为一种兼容的加密算法。可以预见,在不远的几年内,RSA的 应用将来会越来越广泛。 专心-专注-专业