redhat-crypt-md5.c
上传用户:s81996212
上传日期:2007-01-04
资源大小:722k
文件大小:3k
源码类别:

WEB邮件程序

开发平台:

C/C++

  1. /*
  2. ** Copyright 1998 - 1999 Double Precision, Inc.
  3. ** See COPYING for distribution information.
  4. */
  5. #define MD5_INTERNAL
  6. #include "md5.h"
  7. #include <string.h>
  8. static const char rcsid[]="$Id: redhat-crypt-md5.c,v 1.3 1999/12/06 13:22:43 mrsam Exp $";
  9. static char base64[]=
  10.         "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  11. char *md5_crypt_redhat(const char *pw, const char *salt)
  12. {
  13. struct MD5_CONTEXT outer_context, inner_context;
  14. MD5_DIGEST digest;
  15. unsigned pwl=strlen(pw);
  16. unsigned l;
  17. unsigned i, j;
  18. char *p;
  19. static char buffer[100];
  20. if (*salt == '$' && salt[1] == '1' && salt[2] == '$')
  21. salt += 3;
  22. for (l=0; l<8 && salt[l] && salt[l] != '$'; l++)
  23. ;
  24. md5_context_init(&inner_context);
  25. md5_context_hashstream(&inner_context, pw, pwl);
  26. md5_context_hashstream(&inner_context, salt, l);
  27. md5_context_hashstream(&inner_context, pw, pwl);
  28. md5_context_endstream(&inner_context, pwl*2+l);
  29. md5_context_digest(&inner_context, digest);
  30. md5_context_init(&outer_context);
  31. md5_context_hashstream(&outer_context, pw, pwl);
  32. md5_context_hashstream(&outer_context, "$1$", 3);
  33. md5_context_hashstream(&outer_context, salt, l);
  34. for (i=pwl; i; )
  35. {
  36. j=i;
  37. if (j > 16) j=16;
  38. md5_context_hashstream(&outer_context, digest, j);
  39. i -= j;
  40. }
  41. j=pwl*2+l+3;
  42. for (i=pwl; i; i >>= 1)
  43. {
  44. md5_context_hashstream(&outer_context, (i & 1) ? "": pw, 1);
  45. ++j;
  46. }
  47. md5_context_endstream(&outer_context, j);
  48. md5_context_digest(&outer_context, digest);
  49. for (i=0; i<1000; i++)
  50. {
  51. j=0;
  52. md5_context_init(&outer_context);
  53. if (i & 1)
  54. {
  55. md5_context_hashstream(&outer_context, pw, pwl);
  56. j += pwl;
  57. }
  58. else
  59. {
  60. md5_context_hashstream(&outer_context, digest, 16);
  61. j += 16;
  62. }
  63.     
  64. if (i % 3)
  65. {
  66. md5_context_hashstream(&outer_context, salt, l);
  67. j += l;
  68. }
  69.     
  70.      if (i % 7)
  71. {
  72. md5_context_hashstream(&outer_context, pw, pwl);
  73. j += pwl;
  74. }
  75.     
  76. if (i & 1)
  77. {
  78. md5_context_hashstream(&outer_context, digest, 16);
  79. j += 16;
  80. }
  81. else
  82. {
  83. md5_context_hashstream(&outer_context, pw, pwl);
  84. j += pwl;
  85. }
  86. md5_context_endstream(&outer_context, j);
  87. md5_context_digest(&outer_context, digest);
  88. }
  89. strcpy(buffer, "$1$");
  90. strncat(buffer, salt, l);
  91. strcat(buffer, "$");
  92. p=buffer+strlen(buffer);
  93. for (i=0; i<5; i++)
  94. {
  95. unsigned char *d=digest;
  96. j= (d[i] << 16) | (d[i+6] << 8) | d[i == 4 ? 5:12+i];
  97. *p++= base64[j & 63] ; j=j >> 6;
  98. *p++= base64[j & 63] ; j=j >> 6;
  99. *p++= base64[j & 63] ; j=j >> 6;
  100. *p++= base64[j & 63];
  101. }
  102. j=digest[11];
  103. *p++ = base64[j & 63]; j=j >> 6;
  104. *p++ = base64[j & 63];
  105. *p=0;
  106. return (buffer);
  107. }