Provides the Unix crypt() encryption algorithm. : Encrypt Decrypt « Security « C# / C Sharp

Home
C# / C Sharp
1.2D Graphics
2.Class Interface
3.Collections Data Structure
4.Components
5.Data Types
6.Database ADO.net
7.Design Patterns
8.Development Class
9.Event
10.File Stream
11.Generics
12.GUI Windows Form
13.Language Basics
14.LINQ
15.Network
16.Office
17.Reflection
18.Regular Expressions
19.Security
20.Services Event
21.Thread
22.Web Services
23.Windows
24.Windows Presentation Foundation
25.XML
26.XML LINQ
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source
C# / C Sharp » Security » Encrypt DecryptScreenshots 
Provides the Unix crypt() encryption algorithm.
 
// <copyright file="UnixCrypt.cs" company="Cédric Belin">
//    This sourcecode is a port from Java to C#.
//    The original (Java) version was made by John Dumas and can be found at: http://www.dynamic.net.au/christos/crypt/UnixCrypt.txt
// </copyright>
// <summary>
//   Implémentation de la classe <c>DigiWar.Security.Cryptography.UnixCrypt</c>.
// </summary>
// <author>$Author: cedx $</author>
// <date>$Date: 2009-09-10 19:44:34 +0200 (jeu. 10 sept. 2009) $</date>
// <version>$Revision: 1827 $</version>


  using System;
  using System.Linq;
  using System.Text;

  //// 
  
  /// <summary>
  /// Provides the Unix crypt() encryption algorithm.
  /// </summary>
  /// <remarks>
  /// This class is a port from Java source. I do not understand the underlying algorithms, I just converted it to C# and it works.
  /// Because I do not understand the underlying algorithms I cannot give most of the variables useful names. I have no clue what their
  /// significance is. I tried to give the variable names as much meaning as possible, but the original source just called them a, b, c , etc...
  /// 
  /// A very important thing to note is that all ints in this code are UNSIGNED ints! Do not change this, ever!!! It will seriously fuckup the working
  /// of this class. It uses major bitshifting and while Java gives you the >>> operator to signify a right bitshift WITHOUT setting the MSB for
  /// a signed int, C# does not have this operator and will just set the new MSB for you if it happened to be set the moment you bitshifted it.
  /// This is undesirable for most bitshifts and in the cases it did matter, I casted the variable back to an int. This was only required where
  /// a variable was on the right-side of a bitshift operator.
  /// </remarks>
   internal static class UnixCrypt
   {
      /// <value>
      /// The list with characters allowed in a Unix encrypted password.
      /// It is used to randomly chose two characters for use in the encryption.
      /// </value>
      private const string m_encryptionSaltCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
      /// <value>
      /// A lookup-table, presumably filled with some sort of encryption key. 
      /// It is used to calculate the index to the m_SPTranslationTable lookup-table.
      /// </value>
      private static readonly uint[] m_saltTranslation =
                           {
                              0x000x000x000x000x000x000x000x00
                              0x000x000x000x000x000x000x000x00
                              0x000x000x000x000x000x000x000x00
                              0x000x000x000x000x000x000x000x00
                              0x000x000x000x000x000x000x000x00
                              0x000x000x000x000x000x000x000x01
                              0x020x030x040x050x060x070x080x09
                              0x0A0x0B0x050x060x070x080x090x0A
                              0x0B0x0C0x0D0x0E0x0F0x100x110x12
                              0x130x140x150x160x170x180x190x1A
                              0x1B0x1C0x1D0x1E0x1F0x200x210x22
                              0x230x240x250x200x210x220x230x24
                              0x250x260x270x280x290x2A0x2B0x2C
                              0x2D0x2E0x2F0x300x310x320x330x34
                              0x350x360x370x380x390x3A0x3B0x3C
                              0x3D0x3E0x3F0x000x000x000x000x00
      };
      /// <value>
      /// A lookup-table.
      /// It is used to calculate the index to the m_skb lookup-table.
      /// </value>
      private static readonly bool[] m_shifts =
                           {
                              false, false, true, true, true, true, true, true,
                              false, true,  true, true, true, true, true, false
                           };
      /// <value>
      /// A lookup-table.
      /// It is used the dynamically create the schedule lookup-table.
      /// </value>
      private static readonly uint[,m_skb =
                           {
                              {
                                 /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
                                 0x000000000x000000100x200000000x20000010
                                 0x000100000x000100100x200100000x20010010
                                 0x000008000x000008100x200008000x20000810
                                 0x000108000x000108100x200108000x20010810
                                 0x000000200x000000300x200000200x20000030
                                 0x000100200x000100300x200100200x20010030
                                 0x000008200x000008300x200008200x20000830
                                 0x000108200x000108300x200108200x20010830
                                 0x000800000x000800100x200800000x20080010
                                 0x000900000x000900100x200900000x20090010
                                 0x000808000x000808100x200808000x20080810
                                 0x000908000x000908100x200908000x20090810
                                 0x000800200x000800300x200800200x20080030
                                 0x000900200x000900300x200900200x20090030
                                 0x000808200x000808300x200808200x20080830
                                 0x000908200x000908300x200908200x20090830
                           },
                              {
                                 /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */
                                 0x000000000x020000000x000020000x02002000
                                 0x002000000x022000000x002020000x02202000
                                 0x000000040x020000040x000020040x02002004
                                 0x002000040x022000040x002020040x02202004
                                 0x000004000x020004000x000024000x02002400
                                 0x002004000x022004000x002024000x02202400
                                 0x000004040x020004040x000024040x02002404
                                 0x002004040x022004040x002024040x02202404
                                 0x100000000x120000000x100020000x12002000
                                 0x102000000x122000000x102020000x12202000
                                 0x100000040x120000040x100020040x12002004
                                 0x102000040x122000040x102020040x12202004
                                 0x100004000x120004000x100024000x12002400
                                 0x102004000x122004000x102024000x12202400
                                 0x100004040x120004040x100024040x12002404
                                 0x102004040x122004040x102024040x12202404
                           },
                              {
                                 /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */
                                 0x000000000x000000010x000400000x00040001
                                 0x010000000x010000010x010400000x01040001
                                 0x000000020x000000030x000400020x00040003
                                 0x010000020x010000030x010400020x01040003
                                 0x000002000x000002010x000402000x00040201
                                 0x010002000x010002010x010402000x01040201
                                 0x000002020x000002030x000402020x00040203
                                 0x010002020x010002030x010402020x01040203
                                 0x080000000x080000010x080400000x08040001
                                 0x090000000x090000010x090400000x09040001
                                 0x080000020x080000030x080400020x08040003
                                 0x090000020x090000030x090400020x09040003
                                 0x080002000x080002010x080402000x08040201
                                 0x090002000x090002010x090402000x09040201
                                 0x080002020x080002030x080402020x08040203
                                 0x090002020x090002030x090402020x09040203
                           },
                              {
                                 /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */
                                 0x000000000x001000000x000001000x00100100
                                 0x000000080x001000080x000001080x00100108
                                 0x000010000x001010000x000011000x00101100
                                 0x000010080x001010080x000011080x00101108
                                 0x040000000x041000000x040001000x04100100
                                 0x040000080x041000080x040001080x04100108
                                 0x040010000x041010000x040011000x04101100
                                 0x040010080x041010080x040011080x04101108
                                 0x000200000x001200000x000201000x00120100
                                 0x000200080x001200080x000201080x00120108
                                 0x000210000x001210000x000211000x00121100
                                 0x000210080x001210080x000211080x00121108
                                 0x040200000x041200000x040201000x04120100
                                 0x040200080x041200080x040201080x04120108
                                 0x040210000x041210000x040211000x04121100
                                 0x040210080x041210080x040211080x04121108
                           },
                              {
                                 /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */
                                 0x000000000x100000000x000100000x10010000
                                 0x000000040x100000040x000100040x10010004
                                 0x200000000x300000000x200100000x30010000
                                 0x200000040x300000040x200100040x30010004
                                 0x001000000x101000000x001100000x10110000
                                 0x001000040x101000040x001100040x10110004
                                 0x201000000x301000000x201100000x30110000
                                 0x201000040x301000040x201100040x30110004
                                 0x000010000x100010000x000110000x10011000
                                 0x000010040x100010040x000110040x10011004
                                 0x200010000x300010000x200110000x30011000
                                 0x200010040x300010040x200110040x30011004
                                 0x001010000x101010000x001110000x10111000
                                 0x001010040x101010040x001110040x10111004
                                 0x201010000x301010000x201110000x30111000
                                 0x201010040x301010040x201110040x30111004
                           },
                              {
                                 /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */
                                 0x000000000x080000000x000000080x08000008
                                 0x000004000x080004000x000004080x08000408
                                 0x000200000x080200000x000200080x08020008
                                 0x000204000x080204000x000204080x08020408
                                 0x000000010x080000010x000000090x08000009
                                 0x000004010x080004010x000004090x08000409
                                 0x000200010x080200010x000200090x08020009
                                 0x000204010x080204010x000204090x08020409
                                 0x020000000x0A0000000x020000080x0A000008
                                 0x020004000x0A0004000x020004080x0A000408
                                 0x020200000x0A0200000x020200080x0A020008
                                 0x020204000x0A0204000x020204080x0A020408
                                 0x020000010x0A0000010x020000090x0A000009
                                 0x020004010x0A0004010x020004090x0A000409
                                 0x020200010x0A0200010x020200090x0A020009
                                 0x020204010x0A0204010x020204090x0A020409
                           },
                              {
                                 /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */
                                 0x000000000x000001000x000800000x00080100
                                 0x010000000x010001000x010800000x01080100
                                 0x000000100x000001100x000800100x00080110
                                 0x010000100x010001100x010800100x01080110
                                 0x002000000x002001000x002800000x00280100
                                 0x012000000x012001000x012800000x01280100
                                 0x002000100x002001100x002800100x00280110
                                 0x012000100x012001100x012800100x01280110
                                 0x000002000x000003000x000802000x00080300
                                 0x010002000x010003000x010802000x01080300
                                 0x000002100x000003100x000802100x00080310
                                 0x010002100x010003100x010802100x01080310
                                 0x002002000x002003000x002802000x00280300
                                 0x012002000x012003000x012802000x01280300
                                 0x002002100x002003100x002802100x00280310
                                 0x012002100x012003100x012802100x01280310
                           },
                              {
                                 /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */
                                 0x000000000x040000000x000400000x04040000
                                 0x000000020x040000020x000400020x04040002
                                 0x000020000x040020000x000420000x04042000
                                 0x000020020x040020020x000420020x04042002
                                 0x000000200x040000200x000400200x04040020
                                 0x000000220x040000220x000400220x04040022
                                 0x000020200x040020200x000420200x04042020
                                 0x000020220x040020220x000420220x04042022
                                 0x000008000x040008000x000408000x04040800
                                 0x000008020x040008020x000408020x04040802
                                 0x000028000x040028000x000428000x04042800
                                 0x000028020x040028020x000428020x04042802
                                 0x000008200x040008200x000408200x04040820
                                 0x000008220x040008220x000408220x04040822
                                 0x000028200x040028200x000428200x04042820
                                 0x000028220x040028220x000428220x04042822
                           }
      };
      /// <value>
      /// A lookup-table.
      /// It is used to calculate two ints that are used to encrypt the password.
      /// </value>
      private static readonly uint[,m_SPTranslationTable =
                           {
                              {
                                 /* nibble 0 */
                                 0x008202000x000200000x808000000x80820200,
                                 0x008000000x800202000x800200000x80800000,
                                 0x800202000x008202000x008200000x80000200,
                                 0x808002000x008000000x000000000x80020000,
                                 0x000200000x800000000x008002000x00020200,
                                 0x808202000x008200000x800002000x00800200,
                                 0x800000000x000002000x000202000x80820000,
                                 0x000002000x808002000x808200000x00000000,
                                 0x000000000x808202000x008002000x80020000,
                                 0x008202000x000200000x800002000x00800200,
                                 0x808200000x000002000x000202000x80800000,
                                 0x800202000x800000000x808000000x00820000,
                                 0x808202000x000202000x008200000x80800200,
                                 0x008000000x800002000x800200000x00000000,
                                 0x000200000x008000000x808002000x00820200,
                                 0x800000000x808200000x000002000x80020200,
                              },
                              {
                                 /* nibble 1 */
                                 0x100420040x000000000x000420000x10040000,
                                 0x100000040x000020040x100020000x00042000,
                                 0x000020000x100400040x000000040x10002000,
                                 0x000400040x100420000x100400000x00000004,
                                 0x000400000x100020040x100400040x00002000,
                                 0x000420040x100000000x000000000x00040004,
                                 0x100020040x000420040x100420000x10000004,
                                 0x100000000x000400000x000020040x10042004,
                                 0x000400040x100420000x100020000x00042004,
                                 0x100420040x000400040x100000040x00000000,
                                 0x100000000x000020040x000400000x10040004,
                                 0x000020000x100000000x000420040x10002004,
                                 0x100420000x000020000x000000000x10000004,
                                 0x000000040x100420040x000420000x10040000,
                                 0x100400040x000400000x000020040x10002000,
                                 0x100020040x000000040x100400000x00042000,
                              },
                              {
                                 /* nibble 2 */
                                 0x410000000x010100400x000000400x41000040,
                                 0x400100000x010000000x410000400x00010040,
                                 0x010000400x000100000x010100000x40000000,
                                 0x410100400x400000400x400000000x41010000,
                                 0x000000000x400100000x010100400x00000040,
                                 0x400000400x410100400x000100000x41000000,
                                 0x410100000x010000400x400100400x01010000,
                                 0x000100400x000000000x010000000x40010040,
                                 0x010100400x000000400x400000000x00010000,
                                 0x400000400x400100000x010100000x41000040,
                                 0x000000000x010100400x000100400x41010000,
                                 0x400100000x010000000x410100400x40000000,
                                 0x400100400x410000000x010000000x41010040,
                                 0x000100000x010000400x410000400x00010040,
                                 0x010000400x000000000x410100000x40000040,
                                 0x410000000x400100400x000000400x01010000,
                              },
                              {
                                 /* nibble 3 */
                                 0x001004020x040004000x000000020x04100402,
                                 0x000000000x041000000x040004020x00100002,
                                 0x041004000x040000020x040000000x00000402,
                                 0x040000020x001004020x001000000x04000000,
                                 0x041000020x001004000x000004000x00000002,
                                 0x001004000x040004020x041000000x00000400,
                                 0x000004020x000000000x001000020x04100400,
                                 0x040004000x041000020x041004020x00100000,
                                 0x041000020x000004020x001000000x04000002,
                                 0x001004000x040004000x000000020x04100000,
                                 0x040004020x000000000x000004000x00100002,
                                 0x000000000x041000020x041004000x00000400,
                                 0x040000000x041004020x001004020x00100000,
                                 0x041004020x000000020x040004000x00100402,
                                 0x001000020x001004000x041000000x04000402,
                                 0x000004020x040000000x040000020x04100400,
                              },
                              {
                                 /* nibble 4 */
                                 0x020000000x000040000x000001000x02004108,
                                 0x020040080x020001000x000041080x02004000,
                                 0x000040000x000000080x020000080x00004100,
                                 0x020001080x020040080x020041000x00000000,
                                 0x000041000x020000000x000040080x00000108,
                                 0x020001000x000041080x000000000x02000008,
                                 0x000000080x020001080x020041080x00004008,
                                 0x020040000x000001000x000001080x02004100,
                                 0x020041000x020001080x000040080x02004000,
                                 0x000040000x000000080x020000080x02000100,
                                 0x020000000x000041000x020041080x00000000,
                                 0x000041080x020000000x000001000x00004008,
                                 0x020001080x000001000x000000000x02004108,
                                 0x020040080x020041000x000001080x00004000,
                                 0x000041000x020040080x020001000x00000108,
                                 0x000000080x000041080x020040000x02000008,
                              },
                              {
                                 /* nibble 5 */
                                 0x200000100x000800100x000000000x20080800,
                                 0x000800100x000008000x200008100x00080000,
                                 0x000008100x200808100x000808000x20000000,
                                 0x200008000x200000100x200800000x00080810,
                                 0x000800000x200008100x200800100x00000000,
                                 0x000008000x000000100x200808000x20080010,
                                 0x200808100x200800000x200000000x00000810,
                                 0x000000100x000808000x000808100x20000800,
                                 0x000008100x200000000x200008000x00080810,
                                 0x200808000x000800100x000000000x20000800,
                                 0x200000000x000008000x200800100x00080000,
                                 0x000800100x200808100x000808000x00000010,
                                 0x200808100x000808000x000800000x20000810,
                                 0x200000100x200800000x000808100x00000000,
                                 0x000008000x200000100x200008100x20080800,
                                 0x200800000x000008100x000000100x20080010,
                              },
                              {
                                 /* nibble 6 */
                                 0x000010000x000000800x004000800x00400001,
                                 0x004010810x000010010x000010800x00000000,
                                 0x004000000x004000810x000000810x00401000,
                                 0x000000010x004010800x004010000x00000081,
                                 0x004000810x000010000x000010010x00401081,
                                 0x000000000x004000800x004000010x00001080,
                                 0x004010010x000010810x004010800x00000001,
                                 0x000010810x004010010x000000800x00400000,
                                 0x000010810x004010000x004010010x00000081,
                                 0x000010000x000000800x004000000x00401001,
                                 0x004000810x000010810x000010800x00000000,
                                 0x000000800x004000010x000000010x00400080,
                                 0x000000000x004000810x004000800x00001080,
                                 0x000000810x000010000x004010810x00400000,
                                 0x004010800x000000010x000010010x00401081,
                                 0x004000010x004010800x004010000x00001001,
                              },
                              {
                                 /* nibble 7 */
                                 0x082000200x082080000x000080200x00000000,
                                 0x080080000x002000200x082000000x08208020,
                                 0x000000200x080000000x002080000x00008020,
                                 0x002080200x080080200x080000200x08200000,
                                 0x000080000x002080200x002000200x08008000,
                                 0x082080200x080000200x000000000x00208000,
                                 0x080000000x002000000x080080200x08200020,
                                 0x002000000x000080000x082080000x00000020,
                                 0x002000000x000080000x080000200x08208020,
                                 0x000080200x080000000x000000000x00208000,
                                 0x082000200x080080200x080080000x00200020,
                                 0x082080000x000000200x002000200x08008000,
                                 0x082080200x002000000x082000000x08000020,
                                 0x002080000x000080200x080080200x08200000,
                                 0x000000200x082080000x002080200x00000000,
                                 0x080000000x082000200x000080000x00208020
                              }
                           };
      /// <value>
      /// A lookup-table filled with printable characters.
      /// It is used to make sure the encrypted password contains only printable characters. It is filled with
      /// ASCII characters 46 - 122 (from the dot (.) untill (including) the lowercase 'z').
      /// </value>
      private static readonly uint[] m_characterConversionTable =
                           {
                              0x2E0x2F0x300x310x320x330x340x35
                              0x360x370x380x390x410x420x430x44
                              0x450x460x470x480x490x4A0x4B0x4C
                              0x4D0x4E0x4F0x500x510x520x530x54
                              0x550x560x570x580x590x5A0x610x62
                              0x630x640x650x660x670x680x690x6A
                              0x6B0x6C0x6D0x6E0x6F0x700x710x72
                              0x730x740x750x760x770x780x790x7A
                           };
      /// <value>
      /// Marks the size of the dynamically created schedule lookup-table.
      /// </value>
      private const int m_desIterations = 16;

      /// <summary>
      /// Converts four seperate bytes into one uint.
      /// </summary>
      /// <param name="inputBytes">The bytes to use for the conversion.</param>
      /// <param name="offset">The offset at which to start in the inputBytes buffer.</param>
      /// <returns></returns>
      private static uint FourBytesToInt(byte[] inputBytes, uint offset)
      {
         // I used an int here because the compiler would complain the stuff below would require a cast from int to uint.
         // To keep the code cleaner I opted to use an int and cast it when I returned it.
         int resultValue = 0;

         resultValue = (inputBytes[offset++0xFF);
         resultValue |= (inputBytes[offset++0xFF<< 8;
         resultValue |= (inputBytes[offset++0xFF<< 16;
         resultValue |= (inputBytes[offset++]0xFF<< 24;

         return (uint)resultValue;
      }



      /// <summary>
      /// Converts an uint into 4 seperate bytes.
      /// </summary>
      /// <param name="inputInt">The uint to convert.</param>
      /// <param name="outputBytes">The byte buffer into which to store the result.</param>
      /// <param name="offset">The offset to start storing at in the outputBytes buffer.</param>
      private static void IntToFourBytes(uint inputInt, byte[] outputBytes, uint offset)
      {
         outputBytes[offset++(byte)(inputInt & 0xFF);
         outputBytes[offset++(byte)((inputInt >> 80xFF);
         outputBytes[offset++(byte)((inputInt >> 160xFF);
         outputBytes[offset++(byte)((inputInt >> 240xFF);
      }



      /// <summary>
      /// Performs some operation on 4 uints. It's labeled PERM_OP in the original source.
      /// </summary>
      /// <param name="firstInt">The first uint to use.</param>
      /// <param name="secondInt">The second uint to use.</param>
      /// <param name="thirdInt">The third uint to use.</param>
      /// <param name="fourthInt">The fourth uint to use.</param>
      /// <param name="operationResults">An array of 2 uints that are the result of this operation.</param>
      private static void PermOperation(uint firstInt, uint secondInt, uint thirdInt, uint fourthInt, uint[] operationResults)
      {
         // Because here an uint variable is at the right side of a bitshift, I needed to cast it to int. See the remarks of the class itself
         // for more details.
         uint tempInt = ((firstInt >> (int)thirdInt^ secondInt& fourthInt;
         firstInt ^= tempInt << (int)thirdInt;
         secondInt ^= tempInt;

         operationResults[0= firstInt;
         operationResults[1= secondInt;
      }



      /// <summary>
      /// Performs some operation on 3 uints. It's labeled HPERM_OP in the original source.
      /// </summary>
      /// <param name="firstInt">The first uint to use.</param>
      /// <param name="secondInt">The second int to use.</param>
      /// <param name="thirdInt">The third uint to use.</param>
      /// <returns>An int that is the result of this operation.</returns>
      private static uint HPermOperation(uint firstInt, int secondInt, uint thirdInt)
      {
         // The variable secondInt is always used to calculate the number at the right side of a
         // bitshift. It is not used anywhere else, so I made the method parameter an int, to avoid
         // unnecessary casting.
         uint tempInt = ((firstInt << (16 - secondInt)) ^ firstInt& thirdInt;
         uint returnInt = firstInt ^ tempInt ^ (tempInt >> (16 - secondInt));

         return returnInt;
      }



      /// <summary>
      /// This method does some very complex bit manipulations.
      /// </summary>
      /// <param name="encryptionKey">The input data to use for the bit manipulations.</param>
      /// <returns>m_desIterations * 2 number of uints that are the result of the manipulations.</returns>
      private static uint[] SetDESKey(byte[] encryptionKey)
      {
         uint[] schedule = new uint[m_desIterations * 2];

         uint firstInt = FourBytesToInt(encryptionKey, 0);
         uint secondInt = FourBytesToInt(encryptionKey, 4);

         uint[] operationResults = new uint[2];
         PermOperation(secondInt, firstInt, 40x0F0F0F0F, operationResults);
         secondInt = operationResults[0];
         firstInt = operationResults[1];

         firstInt = HPermOperation(firstInt, -20xCCCC0000);
         secondInt = HPermOperation(secondInt, -20xCCCC0000);

         PermOperation(secondInt, firstInt, 10x55555555, operationResults);
         secondInt = operationResults[0];
         firstInt = operationResults[1];

         PermOperation(firstInt, secondInt, 80x00FF00FF, operationResults);
         firstInt = operationResults[0];
         secondInt = operationResults[1];

         PermOperation(secondInt, firstInt, 10x55555555, operationResults);
         secondInt = operationResults[0];
         firstInt = operationResults[1];

         secondInt = (((secondInt & 0xFF<< 16(secondInt & 0xFF00|
            ((secondInt & 0xFF0000>> 16((firstInt & 0xF0000000>> 4));

         firstInt &= 0x0FFFFFFF;

         bool needToShift;
         uint firstSkbValue, secondSkbValue;
         uint scheduleIndex = 0;

         for(int index = 0; index < m_desIterations; index++)
         {
            needToShift = m_shifts[index];
            if(needToShift)
            {
               firstInt = (firstInt >> 2(firstInt << 26);
               secondInt = (secondInt >> 2(secondInt << 26);
            }
            else
            {
               firstInt = (firstInt >> 1(firstInt << 27);
               secondInt = (secondInt >> 1(secondInt << 27);
            }

            firstInt &= 0x0FFFFFFF;
            secondInt &= 0xFFFFFFF;

            firstSkbValue = m_skb[0, firstInt & 0x3F|
               m_skb[1((firstInt >> 60x03((firstInt >> 70x3C)] |
               m_skb[2((firstInt >> 130x0F((firstInt >> 140x30)] |
               m_skb[3((firstInt >> 200x01((firstInt >> 210x06((firstInt >> 220x38)];

            secondSkbValue = m_skb[4, secondInt & 0x3F|
               m_skb[5((secondInt >> 70x03((secondInt >> 80x3C)] |
               m_skb[6(secondInt >> 150x3F|
               m_skb[7((secondInt >> 210x0F((secondInt >> 220x30)];

            schedule[scheduleIndex++((secondSkbValue << 16(firstSkbValue & 0xFFFF)) 0xFFFFFFFF;
            firstSkbValue = ((firstSkbValue >> 16(secondSkbValue & 0xFFFF0000));

            firstSkbValue = (firstSkbValue << 4(firstSkbValue >> 28);
            schedule[scheduleIndex++= firstSkbValue & 0xFFFFFFFF;
         }

         return schedule;
      }



      /// <summary>
      /// This method does some bit manipulations.
      /// </summary>
      /// <param name="left">An input that is manipulated and then used for output.</param>
      /// <param name="right">This is used for the bit manipulation.</param>
      /// <param name="scheduleIndex">The index of an uint to use from the schedule array.</param>
      /// <param name="firstSaltTranslator">The translated salt for the first salt character.</param>
      /// <param name="secondSaltTranslator">The translated salt for the second salt character.</param>
      /// <param name="schedule">The schedule arrray calculated before.</param>
      /// <returns>The result of these manipulations.</returns>
      private static uint DEncrypt(uint left, uint right, uint scheduleIndex, uint firstSaltTranslator, uint secondSaltTranslator, uint[] schedule)
      {
         uint firstInt, secondInt, thirdInt;

         thirdInt = right ^ (right >> 16);
         secondInt = thirdInt & firstSaltTranslator;
         thirdInt = thirdInt & secondSaltTranslator;

         secondInt = (secondInt ^ (secondInt << 16)) ^ right ^ schedule[scheduleIndex];
         firstInt = (thirdInt ^ (thirdInt << 16)) ^ right ^ schedule[scheduleIndex+1];
         firstInt = (firstInt >> 4(firstInt << 28);

         left ^= (m_SPTranslationTable[1, firstInt & 0x3F|
                     m_SPTranslationTable[3(firstInt >> 80x3F|
                     m_SPTranslationTable[5(firstInt >> 160x3F|
                     m_SPTranslationTable[7(firstInt >> 240x3F|
                     m_SPTranslationTable[0, secondInt & 0x3F|
                     m_SPTranslationTable[2(secondInt >> 80x3F|
                     m_SPTranslationTable[4(secondInt >> 160x3F|
                     m_SPTranslationTable[6(secondInt >> 240x3F]);

         return left;
      }



      /// <summary>
      /// Calculates two uints that are used to encrypt the password.
      /// </summary>
      /// <param name="schedule">The schedule table calculated earlier.</param>
      /// <param name="firstSaltTranslator">The first translated salt character.</param>
      /// <param name="secondSaltTranslator">The second translated salt character.</param>
      /// <returns>2 uints in an array.</returns>
      private static uint[] Body(uint[] schedule, uint firstSaltTranslator, uint secondSaltTranslator)
      {
         uint left = 0;
         uint right = 0;
         uint tempInt;

         for(int index = 0; index < 25; index++)
         {
            for(uint secondIndex = 0; secondIndex < m_desIterations * 2; secondIndex += 4)
            {
               left = DEncrypt(left, right, secondIndex, firstSaltTranslator, secondSaltTranslator, schedule);
               right = DEncrypt(right, left, secondIndex + 2, firstSaltTranslator, secondSaltTranslator, schedule);
            }
            
            tempInt = left;
            left = right;
            right = tempInt;
         }

         tempInt = right;
         right = (left >> 1(left << 31);
         left = (tempInt >> 1(tempInt << 31);

         left &= 0xFFFFFFFF;
         right &= 0xFFFFFFFF;

         uint[] operationResults = new uint[2];

         PermOperation(right, left, 10x55555555, operationResults);
         right = operationResults[0];
         left = operationResults[1];

         PermOperation(left, right, 80x00FF00FF, operationResults);
         left = operationResults[0];
         right = operationResults[1];

         PermOperation(right, left, 20x33333333, operationResults);
         right = operationResults[0];
         left = operationResults[1];

         PermOperation(left, right, 160xFFFF, operationResults);
         left = operationResults[0];
         right = operationResults[1];

         PermOperation(right, left, 40x0F0F0F0F, operationResults);
         right = operationResults[0];
         left = operationResults[1];

         uint[] singleOutputKey = new uint[2];
         singleOutputKey[0= left;
         singleOutputKey[1= right;

         return singleOutputKey;
      }


      /// <summary>
      /// Automatically generate the encryption salt (2 random printable characters for use in the encryption) and call the Crypt() method.
      /// </summary>
      /// <param name="textToEncrypt">The text that must be encrypted.</param>
      /// <returns>The encrypted text.</returns>
      public static string Crypt(string textToEncrypt)
      {
         Random randomGenerator = new Random();

         int maxGeneratedNumber = m_encryptionSaltCharacters.Length;
         int randomIndex;
         StringBuilder encryptionSaltBuilder = new StringBuilder();
         for(int index = 0; index < 2; index++)
         {
            randomIndex = randomGenerator.Next(maxGeneratedNumber);
            encryptionSaltBuilder.Append(m_encryptionSaltCharacters[randomIndex]);
         }

         string encryptionSalt = encryptionSaltBuilder.ToString();
         string encryptedString = Crypt(encryptionSalt, textToEncrypt);

         return encryptedString;
      }



      /// <summary>
      /// Encrypts the specified string using the Unix crypt algorithm.
      /// </summary>
      /// <param name="encryptionSalt">2 random printable characters that are used to randomize the encryption.</param>
      /// <param name="textToEncrypt">The text that must be encrypted.</param>
      /// <returns>The encrypted text.</returns>
      public static string Crypt(string encryptionSalt, string textToEncrypt)
      {
         if(encryptionSalt==nullthrow new ArgumentNullException("encryptionSalt");
      if(textToEncrypt==nullthrow new ArgumentNullException("textToEncrypt");
          
      bool isSaltTooSmall = (encryptionSalt.Length < 2);
         if(isSaltTooSmall)
         {
            throw new ArgumentException("The encryptionSalt must be 2 characters big.");
         }

         char firstSaltCharacter = encryptionSalt[0];
         char secondSaltCharacter = encryptionSalt[1];

         // Make sure the string builder is big enough AND filled with 13 characters (the length of the encrypted password).
         // We will use the index operator to set them, but when the characters are not present, even though the string builder
         // has enough capacity, it will throw an exception.
         StringBuilder encryptionBuffer = new StringBuilder("*************");
         encryptionBuffer[0= firstSaltCharacter;
         encryptionBuffer[1= secondSaltCharacter;

         // Use the ASCII value of the salt characters to lookup a number in the salt translation table.
         uint firstSaltTranslator = m_saltTranslation[Convert.ToUInt32(firstSaltCharacter)];
         uint secondSaltTranslator = m_saltTranslation[Convert.ToUInt32(secondSaltCharacter)] << 4;

         // Build the first encryption key table by taking the ASCII value of every character in the text to encrypt and
         // multiplying it by two. Note how the cast will not lose any information. The highest possible ASCII character
         // in a password is the tilde (~), which has ASCII value 126, so the highest possible value after the
         // multiplication would be 252.
         byte[] encryptionKey = new byte[8];
         for(int index = 0; index < encryptionKey.Length && index < textToEncrypt.Length; index++)
         {
            int shiftedCharacter = Convert.ToInt32(textToEncrypt[index]);
            encryptionKey[index(byte)(shiftedCharacter << 1);
         }

         uint[] schedule = SetDESKey(encryptionKey);
         uint[] singleOutputKey = Body(schedule, firstSaltTranslator, secondSaltTranslator);

         byte[] binaryBuffer = new byte[9];
         IntToFourBytes(singleOutputKey[0], binaryBuffer, 0);
         IntToFourBytes(singleOutputKey[1], binaryBuffer, 4);
         binaryBuffer[80;

         uint binaryBufferIndex = 0;
         uint passwordCharacter;
         uint bitChecker = 0x80;
         bool isAnyBitSet, bitCheckerOverflow;
         for(int index = 2; index < 13; index++)
         {
            passwordCharacter = 0;
            for(int secondIndex = 0; secondIndex < 6; secondIndex++)
            {
               passwordCharacter <<= 1;
               isAnyBitSet = ((binaryBuffer[binaryBufferIndex& bitChecker!= 0);
               if(isAnyBitSet)
               {
                  passwordCharacter |= 1;
               }

               bitChecker >>= 1;
               bitCheckerOverflow = (bitChecker == 0);
               if(bitCheckerOverflow)
               {
                  binaryBufferIndex++;
                  bitChecker = 0x80;
               }

               // The original source had the line below, I moved it outside the compound signs, because it will overwrite the value
               // a few times before incrementing the index. Where it is now it will be written only once.
               // Just to be on the safe side, I keep the original line here, so I know where it originally was.
               //encryptionBuffer[index] = Convert.ToChar(m_characterConversionTable[passwordCharacter]);
            }

            encryptionBuffer[index= Convert.ToChar(m_characterConversionTable[passwordCharacter]);
         }
         
         return encryptionBuffer.ToString();
      }
   }

   
  
Related examples in the same category
1.Encrypt Utils
2.Decrypt Utils
3.Encrypts the value by password and salt.
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.