Example #1
0
        public static String Decode(String content, Boolean force)
        {
            StringBuilder builder = new StringBuilder();

            content = force ? Utf8.Decode(content) : content;
            int           i       = 0;
            List <String> strings = new List <String>(content.Length);

            while (i < content.Length)
            {
                uint a = (uint)Base64.Code.IndexOf(content[i]);
                uint b = (uint)Base64.Code.IndexOf(content[i + 1]);
                uint c = (uint)Base64.Code.IndexOf(content[i + 2]);
                uint d = (uint)Base64.Code.IndexOf(content[i + 3]);

                uint e = ((a << 18) | (b << 12) | (c << 6) | d);

                uint f = ((e >> 16) & 0xFF);
                uint g = ((e >> 8) & 0xFF);
                uint h = (e & 0xFF);

                strings.Add(new String(new Char[] { (Char)f, (Char)g, (Char)h }));

                if (d == 64)
                {
                    strings[i / 4] = new String(new Char[] { (Char)f, (Char)g });
                }

                if (c == 64)
                {
                    strings[i / 4] = new String(new Char[] { (Char)f });
                }

                i += 4;
            }

            foreach (var str in strings)
            {
                builder.Append(str);
            }

            return((force) ? Utf8.Decode(builder.ToString()) : builder.ToString());
        }
Example #2
0
        public static String Encode(String content, Boolean force)
        {
            StringBuilder builder = new StringBuilder();
            StringBuilder temp    = new StringBuilder();
            StringBuilder temp2   = new StringBuilder();

            content = (force) ? Utf8.Encode(content) : content;

            int i = content.Length % 3;

            if (i > 0)
            {
                while (i++ < 3)
                {
                    content += "0";
                    temp.Append("=");
                }
            }
            i = 0;
            while (i < content.Length)
            {
                uint a = content[i];
                uint b = content[i + 1];
                uint c = content[i + 2];

                uint d = ((a << 16) | (b << 8) | c);

                uint e = (d >> 18) & 0x3F;
                uint f = (d >> 12) & 0x3F;
                uint g = (d >> 6) & 0x3F;
                uint h = d & 0x3F;

                temp2.Append(new String(new Char[] { Base64.Code[(int)e], Base64.Code[(int)f], Base64.Code[(int)g], Base64.Code[(int)h] }));

                i += 3;
            }

            builder.Append(temp2.ToString().Substring(0, temp2.Length - temp.Length));
            builder.Append(temp);

            return(builder.ToString());
        }
Example #3
0
        public static String Encrypt(String plainText, String password, KeyType keyType)
        {
            int blockSize = 16; // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
            int bits      = (int)keyType;

            plainText = Utf8.Encode(plainText);
            password  = Utf8.Encode(password);

            // use AES itself to encrypt password to get cipher key (using plain password as source for key
            // expansion) - gives us well encrypted key

            int bytes = bits / 8;   // no bytes in key

            int[] pwBytes = new int[bytes];
            for (int i = 0; i < bytes; i++)
            {
                pwBytes[i] = password[i];
            }

            int[] temp = Cipher(pwBytes, KeyExpansion(pwBytes));    // gives us 16-byte key
            int[] key  = new int[temp.Length + bytes - 16];         // expand key to 16/24/32 bytes long
            // expand key to 16/24/32 bytes long
            for (int i = 0; i < temp.Length; i++)
            {
                key[i] = temp[i];
            }
            for (int i = temp.Length; i < (temp.Length + bytes - 16); i++)
            {
                key[i] = temp[i - temp.Length];
            }

            // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes,
            // block counter in 2nd 8 bytes
            int[] counterBlock = new int[16];
            int   nonce        = (int)(DateTime.Now - new DateTime(1970, 1, 1)).TotalMilliseconds; // timestamp: milliseconds since 1-Jan-1970
            int   nonceSec     = (int)Math.Floor((double)nonce / (double)1000);
            int   nonceMs      = nonce % 1000;

            // encode nonce with seconds in 1st 4 bytes, and (repeated) ms part filling 2nd 4 bytes
            for (int i = 0; i < 4; i++)
            {
                counterBlock[i] = (nonceSec >> i * 8) & 0xFF;
            }
            for (int i = 0; i < 4; i++)
            {
                counterBlock[i + 4] = nonceMs & 0xFF;
            }

            // and convert it to a string to go on the front of the ciphertext
            String ctrTxt = String.Empty;

            for (int i = 0; i < 8; i++)
            {
                ctrTxt += (Char)counterBlock[i];
            }

            // generate key schedule - an expansion of the key into distinct Key Rounds for each round
            int[,] keySchedule = KeyExpansion(key);
            int blockCount = (int)Math.Ceiling((double)plainText.Length / (double)blockSize);

            String[] cipherTxt = new String[blockCount];    // ciphertext as array of strings


            for (int i = 0; i < blockCount; i++)
            {
                // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
                // done in two stages for 32-bit ops: using two words allows us to go past 2^32 blocks (68GB)

                for (int j = 0; j < 4; j++)
                {
                    counterBlock[15 - j] = (i >> j * 8) & 0xFF;
                }

                for (int j = 0; j < 4; j++)
                {
                    //counterBlock[15 - c - 4] = (b / 0x100000000 >>> c * 8);
                    counterBlock[15 - j - 4] = 0;
                }

                int[] cipherCntr = Cipher(counterBlock, keySchedule);   // -- encrypt counter block --
                // block size is reduced on final block
                int blockLength = i < (blockCount - 1) ? blockSize : (plainText.Length - i * blockSize);

                Char[] cipherChar = new Char[blockLength];
                for (int j = 0; j < blockLength; j++)
                {
                    // -- xor plaintext with ciphered counter char-by-char --
                    cipherChar[j] = (Char)(cipherCntr[j] ^ plainText[i * blockSize + j]);
                }

                // ciphertxt[b] = cipherChar.join('');
                cipherTxt[i] = new String(cipherChar);
            }

            StringBuilder builder = new StringBuilder();

            builder.Append(ctrTxt);
            foreach (var str in cipherTxt)
            {
                builder.Append(str);
            }

            return(Base64.Encode(builder.ToString(), false));
        }
Example #4
0
        public static String Decrypt(String cipherText, String password, KeyType keyType)
        {
            int blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
            int bits      = (int)keyType;

            cipherText = Base64.Decode(cipherText, false);
            password   = Utf8.Encode(password);

            // use AES to encrypt password (mirroring encrypt routine)
            int bytes = bits / 8;  // no bytes in key

            int[] pwBytes = new int[bytes];
            for (int i = 0; i < bytes; i++)
            {
                pwBytes[i] = password[i];
            }
            int[] temp = Cipher(pwBytes, KeyExpansion(pwBytes));
            int[] key  = new int[temp.Length + bytes - 16];
            // expand key to 16/24/32 bytes long
            for (int i = 0; i < temp.Length; i++)
            {
                key[i] = temp[i];
            }
            for (int i = temp.Length; i < (temp.Length + bytes - 16); i++)
            {
                key[i] = temp[i - temp.Length];
            }

            // recover nonce from 1st 8 bytes of ciphertext
            int[]  counterBlock = new int[16];
            String ctrTxt       = cipherText.Substring(0, 8);

            for (int i = 0; i < 8; i++)
            {
                counterBlock[i] = ctrTxt[i];
            }

            // generate key schedule
            int[,] keySchedule = KeyExpansion(key);

            // separate ciphertext into blocks (skipping past initial 8 bytes)
            int blocks = (int)Math.Ceiling((double)(cipherText.Length - 8) / (double)blockSize);

            String[] ct = new String[blocks];
            for (int i = 0; i < blocks; i++)
            {
                //ct[i] = cipherText.Substring(8 + i * blockSize, blockSize);
                ct[i] = cipherText.Substring(8 + i * blockSize, Math.Min(cipherText.Length - 8 - i * blockSize, blockSize));
            }
            String[] ciphertextArr = ct;  // ciphertext is now array of block-length strings

            // plaintext will get generated block-by-block into array of block-length strings
            String[] plaintxt = new String[ciphertextArr.Length];

            for (int i = 0; i < blocks; i++)
            {
                // set counter (block #) in last 8 bytes of counter block (leaving nonce in 1st 8 bytes)
                for (int j = 0; j < 4; j++)
                {
                    counterBlock[15 - j] = (i >> (j * 8)) & 0xFF;
                }
                for (int j = 0; j < 4; j++)
                {
                    //counterBlock[15 - j - 4] = (((b + 1) / 0x100000000 - 1) >>> c * 8) & 0xff;
                    counterBlock[15 - j - 4] = 0;
                }

                int[] cipherCntr = Cipher(counterBlock, keySchedule);  // encrypt counter block

                Char[] plaintxtByte = new Char[ciphertextArr[i].Length];
                for (int j = 0; j < ciphertextArr[i].Length; j++)
                {
                    // -- xor plaintxt with ciphered counter byte-by-byte --
                    plaintxtByte[j] = (Char)(cipherCntr[j] ^ ciphertextArr[i][j]);
                    //plaintxtByte[j] = String.fromCharCode(plaintxtByte[j]);
                }
                //plaintxt[i] = plaintxtByte.join('');
                plaintxt[i] = new String(plaintxtByte);
            }

            // join array of blocks into single plaintext string
            //var plaintext : String = plaintxt.join('');
            //plaintext = Utf8.decode(plaintext);  // decode from UTF8 back to Unicode multi-byte chars
            StringBuilder builder = new StringBuilder();

            foreach (var str in plaintxt)
            {
                builder.Append(str);
            }

            return(Utf8.Decode(builder.ToString()));
        }