TripleDESCryptoServiceProvider.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. //
  2. // TripleDESCryptoServiceProvider.cs: Default TripleDES implementation
  3. //
  4. // Author:
  5. // Sebastien Pouliot ([email protected])
  6. //
  7. // (C) 2002 Motus Technologies Inc. (http://www.motus.com)
  8. //
  9. using System;
  10. namespace System.Security.Cryptography {
  11. // References:
  12. // a. FIPS PUB 46-3: TripleDES
  13. // http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
  14. // b. ANSI X9.52
  15. // not free :-(
  16. // http://webstore.ansi.org/ansidocstore/product.asp?sku=ANSI+X9%2E52%2D1998
  17. public sealed class TripleDESCryptoServiceProvider : TripleDES {
  18. public TripleDESCryptoServiceProvider () {}
  19. public override void GenerateIV ()
  20. {
  21. IVValue = KeyBuilder.IV (BlockSizeValue >> 3);
  22. }
  23. public override void GenerateKey ()
  24. {
  25. KeyValue = KeyBuilder.Key (KeySizeValue >> 3);
  26. }
  27. public override ICryptoTransform CreateDecryptor (byte[] rgbKey, byte[] rgbIV)
  28. {
  29. Key = rgbKey;
  30. IV = rgbIV;
  31. return new TripleDESTransform (this, false, rgbKey, rgbIV);
  32. }
  33. public override ICryptoTransform CreateEncryptor (byte[] rgbKey, byte[] rgbIV)
  34. {
  35. Key = rgbKey;
  36. IV = rgbIV;
  37. return new TripleDESTransform (this, true, rgbKey, rgbIV);
  38. }
  39. }
  40. // TripleDES is just DES-EDE
  41. internal class TripleDESTransform : SymmetricTransform {
  42. // for encryption
  43. private DESTransform E1;
  44. private DESTransform D2;
  45. private DESTransform E3;
  46. // for decryption
  47. private DESTransform D1;
  48. private DESTransform E2;
  49. private DESTransform D3;
  50. public TripleDESTransform (TripleDES algo, bool encryption, byte[] key, byte[] iv) : base (algo, encryption, iv)
  51. {
  52. byte[] key1 = new byte [8];
  53. byte[] key2 = new byte [8];
  54. byte[] key3 = new byte [8];
  55. DES des = DES.Create ();
  56. Array.Copy (key, 0, key1, 0, 8);
  57. Array.Copy (key, 8, key2, 0, 8);
  58. if (key.Length == 16)
  59. Array.Copy (key, 0, key3, 0, 8);
  60. else
  61. Array.Copy (key, 16, key3, 0, 8);
  62. // note: some modes (like CFB) requires encryption when decrypting
  63. if ((encryption) || (algo.Mode == CipherMode.CFB)) {
  64. E1 = new DESTransform (des, true, key1, iv);
  65. D2 = new DESTransform (des, false, key2, iv);
  66. E3 = new DESTransform (des, true, key3, iv);
  67. }
  68. else {
  69. D1 = new DESTransform (des, false, key3, iv);
  70. E2 = new DESTransform (des, true, key2, iv);
  71. D3 = new DESTransform (des, false, key1, iv);
  72. }
  73. }
  74. // note: this method is garanteed to be called with a valid blocksize
  75. // for both input and output
  76. protected override void ECB (byte[] input, byte[] output)
  77. {
  78. byte[] temp = new byte [input.Length];
  79. if (encrypt) {
  80. E1.ProcessBlock (input, output);
  81. D2.ProcessBlock (output, temp);
  82. E3.ProcessBlock (temp, output);
  83. }
  84. else {
  85. D1.ProcessBlock (input, output);
  86. E2.ProcessBlock (output, temp);
  87. D3.ProcessBlock (temp, output);
  88. }
  89. }
  90. }
  91. }