当前位置:   article > 正文

加密法随机数生成器_加密算法随机数生成器

加密算法随机数生成器

除了传统的线性同余法(即C语言里的rand())产生伪随机数外,还可以用密码来编写能够生成强伪随机数的伪随机数生成器。密码的机密性是支撑伪随机数生成器不可预测性的基础。原理如下图:




有关的DES 的 openssl API和数据结构:

  1. openssl 有关的DES 的API和数据结构
  2. void DES_string_to_key(const char *str, DES_cblock *key)//根据字符串生成ke
  3. int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);//设置密码表,并进行校验
  4. void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);//设置密码表,不需要校验
  5. void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, DES_key_schedule *ks, int enc);//DES ECB模式加解密API
  6. 参数说明:
  7. input:输入数据,8字节
  8. output:输出数据,8字节
  9. ks:密钥
  10. enc:加密-DES_ENCRYPT,解密-DES_DECRYPT
  11. typedef unsigned char DES_cblock[8];
  12. typedef unsigned char const_DES_cblock[8];
  13. typedef struct DES_ks
  14. {
  15. union
  16. {
  17. DES_cblock cblock;
  18. DES_LONG deslong[2];
  19. } ks[16];
  20. } DES_key_schedule;
  21. sizeof(DES_cblock) = 8字节
  22. sizeof(const_DES_cblock ) = 8字节
  23. sizeof(DES_key_schedule) = 128字节


代码:

  1. /*************************************************************************************************
  2. * 1. FILENAME:rand_by_DESencrypt.c
  3. *
  4. * 2.描述: 通过get_seed(seed_text)和get_key_schedule(&key_schedule)分别设置种子(68bit明文)
  5. * 和DES秘钥生成schedule。进而通过函数long long DES_encrypt_rand() 得到DES加密的密文作为
  6. * long long (64bit)类型的随机数,并且打印到屏幕上。种子在每次程序开始运行时读取种子文件
  7. * “./seed.txt”,其它情况在每次调用 DES_encrypt_rand()后自加1。如果seek不变,则随机数机
  8. * 会一样。
  9. *
  10. * 3.DATA : 2017/8/26
  11. * AUTHOR: keyu
  12. *
  13. *************************************************************************************************/
  14. #include<stdio.h>
  15. #include<stdlib.h>
  16. #include<string.h>
  17. #include <openssl/des.h>
  18. char byte2hex_table[16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};//hex2bin表
  19. int byte2hex(unsigned char * hex_string,unsigned char *byte_list,unsigned int byte_list_length);
  20. int get_key_schedule(DES_key_schedule * key_schedule);
  21. int get_seed(const_DES_cblock text);
  22. long long DES_encrypt_rand(DES_key_schedule * key_schedule,const_DES_cblock *seed_text);
  23. int read_file( char * block,char * filename);
  24. int hex2byte(char *hex_string,unsigned char *byte_list, unsigned int byte_list_legth);
  25. int main()
  26. {
  27. int mun = 10;
  28. long long rand;
  29. DES_key_schedule key_schedule;
  30. const_DES_cblock seed_text;
  31. get_key_schedule(&key_schedule);
  32. get_seed(seed_text);
  33. for(int i = 0; i < mun; i++)//生成并且打印10个随机数
  34. {
  35. rand = DES_encrypt_rand(&key_schedule,&seed_text);
  36. printf("%016llX\n",rand);
  37. }
  38. return 1;
  39. }
  40. /*********************************************************************************************
  41. * 1. DES_encrypt_rand()功能:通过key_schedule使用ecd_DES算法加密seed_text得到的64位密
  42. 文作为long long类型的随机数。
  43. *
  44. * 2.参数:DES_key_schedule * key_schedule ---为DES_key转换成的密码表。
  45. * const_DES_cblock * seed_text -----64位明文
  46. *
  47. * 3.RETURN:返回long long 类型的随机数。
  48. *
  49. *********************************************************************************************/
  50. long long DES_encrypt_rand(DES_key_schedule * key_schedule,const_DES_cblock * seed_text)
  51. long long rand;
  52. DES_cblock output;
  53. DES_ecb_encrypt(seed_text, &output, key_schedule, DES_ENCRYPT);
  54. rand = (*((long long *)(output)));
  55. (*((long long*)(*seed_text)))++;
  56. return rand;
  57. }
  58. /*********************************************************************************************
  59. 1.get_key_schedule()功能:初始化一个DES_key_schedule密码表。注意:并不是DES_key.
  60. 如果需要改变密码表,只需改变keystring即可。
  61. *********************************************************************************************/
  62. int get_key_schedule(DES_key_schedule * key_schedule)
  63. {
  64. DES_cblock key;
  65. unsigned char *keystring = "keystring is me!";
  66. DES_string_to_key(keystring, &key);
  67. DES_set_key_checked(&key, key_schedule);
  68. return 0;
  69. }
  70. /*******************************************************************************************
  71. 1.get_seed()功能:从"seed.txt"文件读取种子(明文)。种子是64位二进制数,而文件里
  72. 存放的是其十六进制的字符串形式。所以文件读出来的字符串需要转化为二进制,
  73. 如"a1ff..ff" -> 10011111.....11111111.
  74. 2.参数:const_DES_cblock seed-----8字节大小明文,注意:typedef unsigned char DES_cblock[8];
  75. ********************************************************************************************/
  76. int get_seed(const_DES_cblock seed)
  77. {
  78. unsigned char * block = (unsigned char *)(malloc(16+1));
  79. if( read_file(block,"seed.txt") != 1)
  80. {
  81. printf("delete_read() in read_text() fails!\n");
  82. free(block);
  83. return 0;
  84. }
  85. printf("seed:");
  86. printf("%s\n",block);
  87. unsigned char* byte_list = (unsigned char*)(malloc(8));
  88. if(hex2byte(block,byte_list,8) != 1)
  89. {
  90. printf("hex2byte() in read_text() fails!\n");
  91. free(block);
  92. free(byte_list);
  93. return 0;
  94. }
  95. *((long long*)seed) = *((long long*)byte_list);
  96. free(block);
  97. free(byte_list);
  98. return 1;
  99. }
  100. /**************************************************************************************
  101. *1.hex2byte()功能:把2×byte_list_legth个字符的十六进制字符串(char *hex_string)转化
  102. * 为byte_list_legth个字节的二进制数(unsigned char *byte_list)。
  103. ***************************************************************************************/
  104. int hex2byte(char *hex_string,unsigned char *byte_list, unsigned int byte_list_legth)
  105. {
  106. char * temp;
  107. unsigned int i,j,n;
  108. if( strlen(hex_string) != (2*byte_list_legth) )
  109. {
  110. printf("HEXstring_length != 2*BYTEstring_length!\n");
  111. return 0;
  112. }
  113. temp = hex_string;
  114. for( j = 0; j < byte_list_legth; j++)
  115. {
  116. sscanf( temp, "%02X", &n ); //n必须为unsigned int(因为%X必须要求是整型,而unsigned是防止负数符号扩展问题)
  117. byte_list[j] = (unsigned char)n;
  118. temp += 2;
  119. }
  120. return 1;
  121. }
  122. int read_file( char * block,char * filename)
  123. {
  124. FILE * fp;
  125. fp = fopen(filename, "r");
  126. int i=fread(block,16,1,fp);
  127. if( i != 1)
  128. {
  129. fclose(fp);
  130. return 0;
  131. }
  132. block[16] = 0;
  133. fclose(fp);
  134. return 1;
  135. }


结果:

  1. keyu0915@keyu0915:~/CAR/DES$ gcc rand_by_DEScrypt.c -o rand_by_DEScrypt -lcrypto
  2. keyu0915@keyu0915:~/CAR/DES$ ./rand_by_DEScrypt
  3. seed:EB05AE79F0CE0D2D
  4. 5E3673D90DE27224
  5. A717625519A9DD0D
  6. 43DD9A1F3FC9402F
  7. A456A23EC3276342
  8. 16D05649AD2EAFA3
  9. 941E0A924EF66442
  10. 62EEA7592181FA1F
  11. 5ABA7608EB32D5D2
  12. 24EA761E83DF4F02
  13. 2FA541DDCE3CB9A8



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/895842
推荐阅读
相关标签
  

闽ICP备14008679号