DES.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. //
  2. // System.Security.Cryptography.DES
  3. //
  4. // Author:
  5. // Sergey Chaban ([email protected])
  6. // Sebastien Pouliot ([email protected])
  7. //
  8. // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
  9. //
  10. using System;
  11. using System.Security.Cryptography;
  12. // References:
  13. // a. FIPS PUB 46-3: Data Encryption Standard
  14. // http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
  15. namespace System.Security.Cryptography {
  16. public abstract class DES : SymmetricAlgorithm {
  17. private static int blockSizeByte = 8;
  18. public DES ()
  19. {
  20. KeySizeValue = 64;
  21. BlockSizeValue = 64;
  22. FeedbackSizeValue = 64;
  23. LegalKeySizesValue = new KeySizes[1];
  24. LegalKeySizesValue[0] = new KeySizes(64, 64, 0);
  25. LegalBlockSizesValue = new KeySizes[1];
  26. LegalBlockSizesValue[0] = new KeySizes(64, 64, 0);
  27. }
  28. public static new DES Create ()
  29. {
  30. return Create ("System.Security.Cryptography.DES");
  31. }
  32. public static new DES Create (string algo)
  33. {
  34. return (DES) CryptoConfig.CreateFromName (algo);
  35. }
  36. internal static ulong PackKey (byte [] key)
  37. {
  38. ulong res = 0;
  39. for (int i = 0, sh = 8*blockSizeByte; (sh = sh - 8) >= 0; i++) {
  40. res |= (ulong) key [i] << sh;
  41. }
  42. return res;
  43. }
  44. internal static byte [] UnpackKey (ulong key)
  45. {
  46. byte [] res = new byte [blockSizeByte];
  47. for (int i = 0, sh = 8*blockSizeByte; (sh = sh - 8) >= 0; i++) {
  48. res [i] = (byte) (key >> sh);
  49. }
  50. return res;
  51. }
  52. // Ek(Ek(m)) = m
  53. internal static ulong [] weakKeys = {
  54. 0x0101010101010101, /* 0000000 0000000 */
  55. 0xFEFEFEFEFEFEFEFE, /* FFFFFFF FFFFFFF */
  56. 0x1F1F1F1FE0E0E0E0, /* 0000000 FFFFFFF */
  57. 0xE0E0E0E01F1F1F1F /* FFFFFFF 0000000 */
  58. };
  59. // Ek1(Ek2(m)) = m
  60. internal static ulong [] semiweakKeys = {
  61. 0x01FE01FE01FE01FE, 0xFE01FE01FE01FE01,
  62. 0x1FE01FE00EF10EF1, 0xE01FE01FF10EF10E,
  63. 0x01E001E001F101F1, 0xE001E001F101F101,
  64. 0x1FFE1FFE0EFE0EFE, 0xFE1FFE1FFE0EFE0E,
  65. 0x011F011F010E010E, 0x1F011F010E010E01,
  66. 0xE0FEE0FEF1FEF1FE, 0xFEE0FEE0FEF1FEF1
  67. };
  68. public static bool IsWeakKey (byte [] rgbKey)
  69. {
  70. if (rgbKey.Length == (blockSizeByte >> 3))
  71. throw new CryptographicException ("Wrong Key Length");
  72. ulong lk = PackKey (rgbKey);
  73. foreach (ulong wk in weakKeys) {
  74. if (lk == wk) return true;
  75. }
  76. return false;
  77. }
  78. public static bool IsSemiWeakKey (byte [] rgbKey)
  79. {
  80. if (rgbKey.Length == (blockSizeByte >> 3))
  81. throw new CryptographicException ("Wrong Key Length");
  82. ulong lk = PackKey (rgbKey);
  83. foreach (ulong swk in semiweakKeys) {
  84. if (lk == swk) return true;
  85. }
  86. return false;
  87. }
  88. public override byte[] Key {
  89. get { return base.Key; }
  90. set {
  91. if (value == null)
  92. throw new ArgumentNullException ();
  93. if (IsWeakKey (value) || IsSemiWeakKey (value))
  94. throw new CryptographicException ();
  95. base.Key = value;
  96. }
  97. }
  98. } // DES
  99. } // System.Security.Cryptography