Beispiel #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());
        }
Beispiel #2
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()));
        }