云南大学软件学院 实验报告
课程:信息安全技术技术实验 学期: 任课教师: 许红星
专业:
信息安全
学号:
姓名:
成绩:
实验 2 随机数产生
一、 实验内容
利用密码技术或者专门的随机数产生算法产生随机数,并对产生的随机数进行统计分析。
二、 实验原理
(一) 本次实验使用了两种方法生成随机数,分别如下:
1、使用 RC4 算法产生随机数:
原理:RC4 算法的原理很简单,包括初始化算法和伪随机子密码生成算法两大部分。在初
始化的过程中,密钥的主要功能是将 S-box 搅乱,i 确保 S-box 的每个元素都得到处理,j
保证 S-box 的搅乱是随机的。而不同的 S-box 在经过伪随机子密码生成算法的处理后可以得
到不同的子密钥序列,并且,该序列是随机的。
详细代码请见代码附录。
2、使用 rand 函数生成随机数:
rand 函数不是真正的随机数生成器,而 srand()会设置供 rand()使用的随机数种子。如果你在
第一次调用 rand()之前没有调用 srand(),那么系统会为你自动调用 srand()。而使用同种子相
同的数调用 rand()会导致相同的随机数序列被生成。
因此,在这个实验中,我使用了时间作为随机数种子,时间时刻在变化,因此每次生成的
随机数都是不同的
详细代码请见代码附录。
(二) 生成的随机数序列,我采用了 matlab 对随机数进行统计分析。
三、 实验步骤
(一) 我使用 RC4 加密过程产生的密钥流即为产生的随机数,文件有多大就会产生多少个随
机数,这里我产生了 100 个随机数,如图 1 所示:
图 1 使用 RC4 产生 100 个随机数
1
对这 100 个随机数使用 matlab 进行分析可得到的 100 随机数的产生序列图,如图 2 所示
图 2 RC4 生成的 100 个随机数的序列图
由这个序列图,我们能清晰地看到这 100 个随机数的分布情况,具有完全的随机性,没有
出现周期性的变化;
(二) 使用 RC4 加密过程产生的密钥流即为产生的随机数,文件有多大就会产生多少个随机
数,这里我产生了 500 个随机数,如图 3 所示:
2
图 3 使用 RC4 产生 500 个随机数
对这 500 个随机数使用 matlab 进行分析可得到的 500 随机数的产生序列图,如图 4 所示;
3
图 4 RC4 生成的 500 个随机数的序列图
这 500 个随机数大小是 0 到 256;它们的分布有图 2 所示,是完全随机的,不会出现某种规
律,也不会过了一段就重复。
(三) 使用 rand 函数产生 100 个随机数,使用时间作为种子,产生结果如图 5 所示;
对这 100 个随机数使用 matlab 进行分析可得到的 100 随机数的产生序列图,如图 6 所示;
图 5 使用 Rand 函数产生 100 个随机数
4
图 6 RC4 生成的 100 个随机数的序列图
由这个序列图,我们能清晰地看到这 100 个随机数的分布情况,具有完全的随机性,没有
出现周期性的变化;前面一段是产生随机数成增大的趋势,增大到了一定程度,整体又是
减小的趋势,由于只有 100 个,看不出后面的变化,下面产生更多的随机数。
(四) 使用 rand 函数产生 500 个随机数,使用时间作为种子,产生结果如图 7 所示;
图 7 使用 Rand 函数产生 500 个随机数
5
对这 500 个随机数使用 matlab 进行分析可得到的 500 随机数的产生序列图,如图 8 所示;
图 8 RC4 生成的 500 个随机数的序列图
这 500 个随机数大小是 1 到 100;它们的分布有图 8 所示,是完全随机的,不会出现某种规
律,也不会过了一段就重复。在
四、 实验总结
在这个实验中,通过分别使用两种方法:RC4 密码算法和 rand 函数方法,分别产生 100 和
500 个随机数,两种方法都能产生随机性较好的随机数。然后我通过 matlab 分析产生的随
机数的随机性,发现随机数的随机性都是随机的,没有出现周期性的重复现象。
6
代码附录:
一、RC4 算法产生的随机密钥流算法:
#include
#include
#include
#include
//交换函数。
void swap(unsigned char a[], unsigned char b[])
{
unsigned char temp;
temp = *a;
*a = *b;
*b = temp;
}
//RC4 初始化,也就是进行 S 的初始化和初始置换。
void Initial_RC4(unsigned char key[], unsigned char S[], unsigned long
{
key_len)
int i, j;
unsigned char temp = 0;
unsigned char T[257];
//S 初始化
for (i = 0; i < 256; i++)
{
S[i] = i;
T[i] = key[i%key_len];
}
//S 初始置换
for (i = 0, j = 0; i < 256; i++)
{
j = (j + S[i] + T[i]) % 256;
swap(&S[i], &S[j]);
}
}
//RC4 的加解密函数:加密是传入的明文异或密钥流,解密是传入的密文异或密钥流
void Encrypt_Decrypt_RC4(unsigned char S[], unsigned char p[], unsigned char c[], unsigned long len)
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char temp = 0;
printf("\n 产生的随机数:\n");
for (k = 0; k < len; k++)
{
7
i = (i + 1) % 256;
j = (j + S[i]) % 256;
swap(&S[i], &S[j]);
t = (S[i] + S[j]) % 256;
printf("%d ", S[t]);
c[k] = p[k] ^ S[t];
}
//产生的密钥流 S[t]
}
//主函数:选择进行加密(e)还是解密(d),输入密钥,输入两个文件名,打开文件进行加密或解密,
写明文或密文进文件。
int main(int argc, char* argv[])
{
//指向明文的指针
//用于保存明文长度
unsigned char key[256] = { 0 };//保存输入的密钥
unsigned char S[257] = { 0 };//用于 S 的初始化和初始置换。
unsigned char *p = 0;
unsigned char *c = 0; //指向密文的指针
unsigned long len = 0;
unsigned long key_len = 0; //密钥长度
char sw;
char inputfilepath[30], outputfilepath[30]; //保存两个文件路径
FILE *fp = NULL, *fp2 = NULL; //文件指针
clock_t start, end;
//时钟,用于计算加解密花费的时间。
//用于用户选择进行加密还是解密
if (argv[1] == NULL)
{
printf("------------ RC4 file encrypt or decrypt(by )
printf("input order:\n-e(encrypt) or -d(decrypt)
------------\n");
key(0-255 字节)
inputfile
outputfile :
\n");
}
return 0;
//scanf("%c", &sw);
//getchar();
//scanf("%s", &key);
//scanf("%s", inputfilepath);
//scanf("%s", outputfilepath);
//输入文件路径及文件名
key_len = strlen(argv[2]);
p = (unsigned char *)malloc((1048576)*sizeof(unsigned char));
c = (unsigned char *)malloc((1048576)*sizeof(unsigned char));
//申请 1M 的空间存储明密文
int i = 0;
switch (argv[1][1])
{
//选择进行哪种操作
8