2)发送节点发送消息,接收节点接收后验证消息并显示,对应步骤6。
3)发送节点使用秘密值计算MD,但接收节点没有使用秘密值或者不知道秘密值,对应步骤7。
16
4)发送节点使用秘密值计算MD,接收节点使用相同的秘密值认证消息,对应步骤8。 对实验结果中出现乱码(非ASCII字符)的情形,要说明为什么出现?
六、实验总结
经过本次实验,我较为熟练地掌握了消息摘要Hash算法的原理和消息认证的方法,能够自己完成编写一个消息摘要认证函数,并且学会了在消息认证过程中如何进行加密。
17
实验四 公钥加密算法实验
一、实验目的
掌握消息RSA密钥生成和加密算法的原理。 二、实验环境
硬件:ZXBee CC2530 节点板 2 块、USB 接口的 CC2530 仿真器,PC 机; 软件:Windows 7/Windows XP、IAR 集成开发环境、串口监控程序。 三、实验原理
RSA算法的关键是生成公钥私钥对。本实验采用了一个简化的算法,通过一个给定的seed(实验组号)搜索两个不同的素数(100以内),并计算出公钥PubliceKey(e,n)和私钥PrivateKey(d,n)。
RSA加/解密公式为C=Pe mod n和P=Cd mod n,其中的幂指数运算速度慢,可采用下面的公式进行转换:
C=Pe mod n=((...((P*P mod n)*P mod n)*P mod n)... ...)*P mod n
此外,RSA算法的明文和密文均为0到n-1之间的整数,而一般传送消息的长度单位为字节(8 bits),n的大小与消息长度难以匹配。因此,本实验采用如下的特殊处理方法:
(1)令选定公钥/私钥的n值小于65536,即n值小于16bits的二进制。 (2)将消息的每个字节(8bits)作为一个明文块。
(3)每个明文块进行RSA加密后,得到的密文块为16bits,用2个字节存放。即密文的长度为明文的2倍。
(4)接收方收到的密文,按2个字节为一个密文块进行RSA解密,解密后的结果只保留低8bits。 四、实验步骤
1)本实验程序可在《指导书》4.4节程序上进行修改,可节约时间。信道编号不用更改。 2)增加下列有关公钥和私钥的定义(全局定义)。
typedef struct { unsigned int e; unsigned int n; }RSA_PUBLICKEY; typedef struct { unsigned int d;
18
unsigned int n; }RSA_PRIVATEKEY; typedef struct { RSA_PUBLICKEY Pu; RSA_PRIVATEKEY Pr; }RSA_KEY; 3)增加一个RSA公钥/私钥产生函数。 RSA_KEY CreateRSAKey(unsigned int seed) { RSA_KEY RSAKey; unsigned int i,j; unsigned int a,b,temp; unsigned int p=0,q=0,fi=0; i=(seed*71-17))+11; //产生第一个素数搜索的初始值,只搜索11~39 //搜索素数p while(p==0){ for(j=2;j<=i/2-1;j++) if(i%j==0) break; if(j>(i/2-1) && p==0) p=i; i=(i-10))+11; } i=(seed*171-51))+11; //产生第二个素数搜索的初始值,只搜索11~39 //搜索素数q while(q==0){ for(j=2;j<=i/2-1;j++) if(i%j==0) break; if(j>(i/2-1) && i!=p && q==0) q=i; i=(i-10))+11; } RSAKey.Pu.n=p*q; RSAKey.Pr.n=p*q; fi=(p-1)*(q-1); //找出一个小于fi且与fi互素的e for(i=3;i 19 b=i; while(b!=0) { //使用辗转相除法,判断是否互素 temp=b; b=a%b; a=temp; } if(a==1){ RSAKey.Pu.e=i; break; } } //计算d j=1; while((fi*j+1)%RSAKey.Pu.e!=0) j++; RSAKey.Pr.d=(fi*j+1)/RSAKey.Pu.e; //printf(\ //printf(\ return RSAKey; } 4)增加一个RSA加密函数。 //RSA加密函数,PlainText为8bit数组,CipherText为16bits数组,Len为PlainText长度 void RSA_Encrypt( RSA_PUBLICKEY PuKey, uint8 *PlainText, uint16 *CipherText, int Len ) { int i=0, j=0; uint16 temInt = 0; for( i=0; i 字段名称 长度(字节) 接收方编号 1 明文长度 1 密文 2~256 代码: 20