using System;
using System.Text;
using System.Diagnostics;
using CryptoSysAPI;

/*
 $Id: TdeaBytesAndHex.cs $

 Examples showing how to encrypt a arbitrary-length 'text' string
 with CryptoSys API using both 'Bytes' and `Hex' modes.

 TDEA_Bytes_Example uses data in `Byte' format
 TDEA_Hex_Example uses data in `Hex' format

Algorithm: Triple DES (TDEA, 3DES, des-ede3)
Mode:      Cipher Block Chaining (CBC)
Padding:   PKCS-7 Padding (same as PKCS-5)
Key:       F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677
IV:        FEDCBA9876543210
Plaintext = "Hello world!"

 Copyright (C) 2006-17 DI Management Services Pty Limited.
 All rights reserved.
 <http://www.cryptosys.net/contact>
 Last updated:
 $Date: 2017-03-23 13:59:00 $
 Use at your own risk.
*/

namespace TdeaBytesAndHex
{
    class TdeaBytesAndHex
    {
        static void Main(string[] args)
        {
            Console.WriteLine("API Version={0}", General.Version());
            TDEA_Bytes_Example();
            TDEA_Hex_Example();
            TDEA_Wide_Example();
        }
        static void TDEA_Bytes_Example()
        {
            byte[] ct, p1;
            string s1;

            Console.WriteLine("USING `BYTE` PARAMETERS...");
            // SET INPUT PARAMETERS
            byte[] key = Cnv.FromHex("F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677");
            byte[] iv = Cnv.FromHex("FEDCBA9876543210");
            string strPlain = "Hello world!";
            // SHOW PARAMETERS
            Console.WriteLine("KY={0}", Cnv.ToHex(key));
            Console.WriteLine("IV={0}", Cnv.ToHex(iv));
            Console.WriteLine("SZ='{0}'", strPlain);
            // CONVERT PLAINTEXT STRING TO BYTE ARRAY
            byte[] plain = System.Text.Encoding.Default.GetBytes(strPlain);
            Console.WriteLine("PT={0}", Cnv.ToHex(plain));

            // ENCRYPT USING tdea/cbc/pkcs5
            // (can do in one when using "byte" parameters)
            ct = Cipher.Encrypt(plain, key, iv, CipherAlgorithm.Tdea, Mode.CBC, Padding.Pkcs5);
            Console.WriteLine("CT={0}", Cnv.ToHex(ct));

            // DECRYPT IT
            p1 = Cipher.Decrypt(ct, key, iv, CipherAlgorithm.Tdea, Mode.CBC, Padding.Pkcs5);
            Console.WriteLine("P'={0}", Cnv.ToHex(p1));

            // CONVERT BYTES TO STRING
            s1 = System.Text.Encoding.Default.GetString(p1);
            Console.WriteLine("SZ='{0}'", s1);
        }

        static void TDEA_Hex_Example()
        {
            string pthex, blkhex, p1hex, s1;

            Console.WriteLine("USING `HEX` PARAMETERS...");
            // SET INPUT PARAMETERS
            string keyhex = "F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677";
            string ivhex = "FEDCBA9876543210";
            string strPlain = "Hello world!";
            Console.WriteLine("KY={0}", keyhex);
            Console.WriteLine("IV={0}", ivhex);
            Console.WriteLine("SZ='{0}'", strPlain);

            // CONVERT PLAINTEXT STRING TO HEX-ENCODED FORMAT
            pthex = Cnv.ToHex(strPlain);
            Console.WriteLine("PT={0}", pthex);

            // ENCRYPT USING tdea/cbc/pkcs5
            // (with hex parameters we need to pad separately)
            // PAD INPUT BLOCK
            blkhex = Cipher.Pad(pthex, CipherAlgorithm.Tdea, Padding.Pkcs5);
            Console.WriteLine("IB={0}", blkhex);
            // ENCRYPT IT
            string cthex = Tdea.Encrypt(blkhex, keyhex, Mode.CBC, ivhex);
            Console.WriteLine("CT={0}", cthex);

            // DECRYPT IT
            blkhex = Tdea.Decrypt(cthex, keyhex, Mode.CBC, ivhex);
            Console.WriteLine("OB={0}", blkhex);
            // STRIP PADDING
            p1hex = Cipher.Unpad(blkhex, CipherAlgorithm.Tdea, Padding.Pkcs5);
            Console.WriteLine("P'={0}", p1hex);

            // CONVERT HEX TO STRING
            s1 = Cnv.StringFromHex(p1hex);
            Console.WriteLine("SZ='{0}'", s1);
        }
        static void TDEA_Wide_Example()
        {
            byte[] ct, p1;
            string s1;

            Console.WriteLine("USING `WIDE` CHARACTERS...");
            // SET INPUT PARAMETERS
            byte[] key = Cnv.FromHex("F0E1D2C3B4A5968778695A4B3C2D1E0F0011223344556677");
            byte[] iv = Cnv.FromHex("FEDCBA9876543210");
            string strPlain = "Hello world!";
            // SHOW PARAMETERS
            Console.WriteLine("KY={0}", Cnv.ToHex(key));
            Console.WriteLine("IV={0}", Cnv.ToHex(iv));
            Console.WriteLine("SZ='{0}'", strPlain);
            // CONVERT PLAINTEXT STRING TO BYTE ARRAY 
            // using "Unicode" encoding
            byte[] plain = System.Text.Encoding.Unicode.GetBytes(strPlain);
            Console.WriteLine("PT={0}", Cnv.ToHex(plain));

            // ENCRYPT USING tdea/cbc/pkcs5
            ct = Cipher.Encrypt(plain, key, iv, CipherAlgorithm.Tdea, Mode.CBC, Padding.Pkcs5);
            Console.WriteLine("CT={0}", Cnv.ToHex(ct));

            // DECRYPT IT
            p1 = Cipher.Decrypt(ct, key, iv, CipherAlgorithm.Tdea, Mode.CBC, Padding.Pkcs5);
            Console.WriteLine("P'={0}", Cnv.ToHex(p1));

            // CONVERT BYTES TO STRING
            s1 = System.Text.Encoding.Unicode.GetString(p1);
            Console.WriteLine("SZ='{0}'", s1);
        }
    }
}