예제 #1
0
        static void DoAllTheJobWithText(
            string text, CustomRSA Key,
            List <BigInteger> cur_data,
            List <BigInteger> enc_data,
            List <BigInteger> dec_data)
        {
            int blocklength = Key.KeyLength / 8;

            byte[] data = ENC.GetBytes(text);
            BytesToList(blocklength, data, cur_data);

            w("\n\n текущий текст: ");
            WriteList(cur_data, blocklength);

            EncodeText(Key, cur_data, enc_data);
            w("\n\n encoded текст: ");
            WriteListBASE64(enc_data, blocklength);

            /*DecodeText(Key, enc_data, dec_data);
             * w("\n\n non-optimized: ");
             * WriteList(dec_data, blocklength);*/

            DecodeTextOptimized(Key, enc_data, dec_data);
            w("\n\n     optimized: ");
            WriteList(dec_data, blocklength);
        }
예제 #2
0
 static void EncodeText(CustomRSA Key, List <BigInteger> cur_data, List <BigInteger> enc_data)
 {
     enc_data.Clear();
     for (int i = 0; i < cur_data.Count(); i++)
     {
         enc_data.Add(cur_data[i].ModPow(Key.E, Key.N));
     }
 }
예제 #3
0
 static void DecodeText(CustomRSA Key, List <BigInteger> enc_data, List <BigInteger> dec_data)
 {
     dec_data.Clear();
     for (int i = 0; i < enc_data.Count(); i++)
     {
         dec_data.Add(enc_data[i].ModPow(Key.D, Key.N));
     }
 }
예제 #4
0
        static void DecodeTextOptimized(CustomRSA Key, List <BigInteger> enc_data, List <BigInteger> dec_data)
        {
            BigInteger m0 = BigInteger.Zero;
            BigInteger m1 = BigInteger.Zero;
            BigInteger m2 = BigInteger.Zero;
            BigInteger h  = BigInteger.Zero;

            dec_data.Clear();
            for (int i = 0; i < enc_data.Count(); i++)
            {
                m1 = enc_data[i].ModPow(Key.DP, Key.P);
                m2 = enc_data[i].ModPow(Key.DQ, Key.Q);
                h  = Key.QINV.Multiply(m1.Subtract(m2)).Mod(Key.P);
                m0 = m2.Add(h.Multiply(Key.Q));

                dec_data.Add(m0);
            }
        }
예제 #5
0
        /*
         * public static byte[] KeyExchange(byte[] publicKey, byte[] privateKey)
         * {
         *  var sharedKey = new byte[32];
         *  KeyExchange(new ArraySegment<byte>(sharedKey), new ArraySegment<byte>(publicKey), new ArraySegment<byte>(privateKey));
         *  return sharedKey;
         * }
         * public static void KeyExchange(ArraySegment<byte> sharedKey, ArraySegment<byte> publicKey, ArraySegment<byte> privateKey)
         * {
         *  if (sharedKey.Array == null)
         *      throw new ArgumentNullException("sharedKey.Array");
         *  if (publicKey.Array == null)
         *      throw new ArgumentNullException("publicKey.Array");
         *  if (privateKey.Array == null)
         *      throw new ArgumentNullException("privateKey");
         *  if (sharedKey.Count != 32)
         *      throw new ArgumentException("sharedKey.Count != 32");
         *  if (publicKey.Count != 32)
         *      throw new ArgumentException("publicKey.Count != 32");
         *  if (privateKey.Count != 64)
         *      throw new ArgumentException("privateKey.Count != 64");
         * }
         */
        #endregion

        static void Main(string[] args)
        {
            Console.SetWindowSize(100, 25);
            //Console.OutputEncoding = ENC;

            int menu = 0;

            wl("выберите, что хотите проверить");
            wl("1. нормальная работа rsa");
            wl("2. факторизация числа N");
            wl("3. атака Винера");
            wl("4. атака повторного шифрования");
            wl("5. атака бесключевого шифрования");
            wl("6. закладка в публичный ключ");
            wl("0. ничего");
            w("          ваше решение: ");
            ri(ref menu);

            int keylength = 0;

            w(" размер ключей в битах: ");
            if (menu < 6)
            {
                ri(ref keylength);
            }
            else
            {
                keylength = 2048;
            }

            #region инициализация переменных
            Stopwatch          stopwatch = new Stopwatch();
            List <ElapsedTime> times     = new List <ElapsedTime>();
            List <TimeSpan>    avgt1     = new List <TimeSpan>();
            List <TimeSpan>    avgt2     = new List <TimeSpan>();
            TimeSpan[]         avg_time  = new TimeSpan[2];

            // инициализация всех нужных переменных
            BigInteger p  = BigInteger.Zero;
            BigInteger q  = BigInteger.Zero;
            BigInteger N  = BigInteger.Zero;
            BigInteger ww = BigInteger.Zero;
            BigInteger e  = BigInteger.Zero;
            BigInteger d  = BigInteger.Zero;

            BigInteger dp   = BigInteger.Zero;
            BigInteger dq   = BigInteger.Zero;
            BigInteger qinv = BigInteger.Zero;

            BigInteger debug = BigInteger.Zero;

            //w(" введите текст: ");
            //string s = rs();
            string s =
                "QWERTYUIOPASDFGHJKLZXCVBNM" +
                "qwertyuiopasdfghjklzxcvbnm" +
                "ЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ" +
                "йцукенгшщзхъфывапролджэячсмитьбю" +
                "0123456789" +
                "-=!@#$%^&*()_+[];'\\,./{}:\"|<>?";

            byte[]            data     = ENC.GetBytes(s);
            List <BigInteger> cur_data = new List <BigInteger>();
            List <BigInteger> enc_data = new List <BigInteger>();
            List <BigInteger> dec_data = new List <BigInteger>();

            //int rounds = 1;
            //w("    количество раундов: ");
            //ri(ref rounds);
            #endregion

            #region работа rsa (obsolete)

            /*
             * wl("~~ генерация p и q ~~");
             * p = BigInteger.ProbablePrime(keylength, new SecureRandom());
             * q = BigInteger.ProbablePrime(keylength, new SecureRandom());
             *
             * N = p.Multiply(q);
             * ww = p.Subtract(BigInteger.One).Multiply(q.Subtract(BigInteger.One));
             *
             * wl(" p = " + p + "\n q = " + q);
             * wl(" N = p * q = " + N);
             * wl(" w(N) = (p - 1) * (q - 1) = " + ww);
             *
             * wl("~~ генерация e и d ~~");
             * do
             * {
             *  e = BigInteger.ProbablePrime(keylength, new SecureRandom());
             * } while (ww.Mod(e).Equals(0));
             * d = e.ModInverse(ww);
             *
             * wl(" e = " + e);
             * wl(" d = " + d);
             *
             * // вычисления для оптимизации
             * dp = d.Mod(p.Subtract(BigInteger.One));
             * dq = d.Mod(q.Subtract(BigInteger.One));
             * qinv = q.ModInverse(p);
             */
            #endregion
            #region внедрение закладки (obsolete)

            /*byte[] seed, payload;
             * MakeSeedAndPayload(out seed, out payload);
             * var randomKeyPair = BuildKey(seed, payload);
             *
             * payload = ExtractPayload((RsaKeyParameters)randomKeyPair.Public);
             * var restoredKey = BuildKeyFromPayload(payload);
             *
             * var initialParams = ((RsaPrivateCrtKeyParameters)randomKeyPair.Private);
             * var restoredParams = ((RsaPrivateCrtKeyParameters)restoredKey.Private);*/
            #endregion
            #region внедрение закладки 2 (obsolete)

            /*
             * // генерируем ключевую пару RSA, используя ГПСЧ и seed
             * var publicExponent = new BigInteger("10001", 16);
             * var keygen = new RsaKeyPairGenerator();
             * byte[] seed = new byte[32], payload = new byte[32];
             * MakeSeedAndPayload(out seed, out payload);
             *
             * keygen.Init(new RsaKeyGenerationParameters(publicExponent, new SecureRandom(new SeededGenerator(seed)), 2048, 80));
             * var pair = keygen.GenerateKeyPair();
             *
             * // берем модуль p*q и заменяем в нем часть байт на payload
             * var paramz = ((RsaPrivateCrtKeyParameters)pair.Private);
             * var modulus = paramz.Modulus.ToByteArray();
             * Replace(modulus, payload, 80);  // 80 - это смещение
             *
             * // считаем остальные параметры
             * p = paramz.P;
             * var n = new BigInteger(modulus);
             * var preQ = n.Divide(p);
             * q = preQ.NextProbablePrime();
             *
             * // считаем все параметры ключевой пары, кроме, p, заново
             * var newKeyPair = ComposeKeyPair(p, q, publicExponent);
             *
             * // извлекаем payload
             * byte[] extractedPayload = ExtractPayload((RsaKeyParameters)newKeyPair.Public);
             * // вычисляем seed и прогоняем процесс заново, чтобы получить закрытый ключ
             * var chackedKey = BuildKeyFromPayload(extractedPayload);
             */
            #endregion
            #region проверка работы (obsolete)

            /*
             * List<BigInteger> dec_data_1 = new List<BigInteger>();
             * List<BigInteger> dec_data_2 = new List<BigInteger>();
             *
             * int blocklength = keylength / 8;
             *
             * // разбить текст на блоки и сохранить их в лист
             * for (int i = 0; i < data.Count(); i += blocklength)
             * {
             *  byte[] temp = new byte[blocklength];
             *  for (int j = 0; j < blocklength; j++)
             *  {
             *      if (i + j >= data.Count())
             *          temp[j] = 0;
             *      else
             *          temp[j] = data[i + j];
             *  }
             *  cur_data.Add(new BigInteger(temp));
             *  //k++;
             * }
             *
             *
             * w("\n\n текущий текст: ");
             * WriteList(cur_data, blocklength);
             *
             * // зашифровать текст
             * for (int i = 0; i < cur_data.Count(); i++)
             *  enc_data.Add(cur_data[i].ModPow(e, N));
             *
             * w("\n\n encoded текст: ");
             * WriteListBASE64(enc_data, blocklength);
             *
             *
             * // неоптимизированная расшифровка
             * for (int i = 0; i < enc_data.Count(); i++)
             *  dec_data_1.Add(enc_data[i].ModPow(d, N));
             *
             * w("\n\n non-optimized: ");
             * WriteList(dec_data_1, blocklength);
             *
             *
             * // оптимизированная расшифровка
             * BigInteger m0 = BigInteger.Zero;
             * BigInteger m1 = BigInteger.Zero;
             * BigInteger m2 = BigInteger.Zero;
             * BigInteger h = BigInteger.Zero;
             *
             * for (int i = 0; i < enc_data.Count(); i++)
             * {
             *  m1 = enc_data[i].ModPow(dp, p);
             *  m2 = enc_data[i].ModPow(dq, q);
             *  h = qinv.Multiply(m1.Subtract(m2)).Mod(p);
             *  m0 = m2.Add(h.Multiply(q));
             *
             *  dec_data_2.Add(m0);
             * }
             * w("\n\n     optimized: ");
             * WriteList(dec_data_2, blocklength);
             *
             * w("\n\n____________________\n\n");
             */
            #endregion

            wl("\n\n\n");

            CustomRSA Key = new CustomRSA(keylength);
            //Key.GenParams();
            //Key.P = BigInteger.ProbablePrime(keylength, new SecureRandom());
            //Key.Q = BigInteger.ProbablePrime(keylength, new SecureRandom());
            //Key.Q = Key.P.NextProbablePrime();
            Key.N = Key.P.Multiply(Key.Q);
            wl("n = " + Key.N);
            wl("p = " + Key.P + ", q = " + Key.Q);

            string     msg = "m";
            BigInteger MSG = new BigInteger(ENC.GetBytes(msg));

            dynamic result;
            switch (menu)
            {
            case 1:     // обычная работа алгоритма

                break;

            case 2:     // факторизация Ферма
                Key.P = BigInteger.ProbablePrime(keylength, new SecureRandom());
                Key.Q = Key.P.NextProbablePrime();
                Key.N = Key.P.Multiply(Key.Q);
                wl(" n = " + Key.N);
                wl(" p = " + Key.P);
                wl(" q = " + Key.Q);

                stopwatch.Start();
                result = FermatFactoringMethod(Key.N);
                AddElapsedTime("", times, stopwatch);
                showTimeElapsed(times);

                wl(" результат факторизации:");
                wl(" множитель 1: " + result.Item1);
                wl(" множитель 2: " + result.Item2);
                break;

            case 3:     // атака Винера
                Key.GenParams();
                // генерация параметров для успешного выполнения атаки
                BigInteger limitD    = BigIntSqrt(BigIntSqrt(Key.N)).Divide(BigInteger.Three);
                int        maxlength = limitD.BitLength;
                do
                {
                    Key.E = BigInteger.ProbablePrime(maxlength - maxlength % 8, new SecureRandom());
                } while (Key.WW.Mod(Key.E).Equals(0) && limitD.CompareTo(Key.E) != 1);
                Key.D = Key.E.ModInverse(Key.WW);
                // обмен D и E
                BigInteger temp = Key.D;
                Key.D = Key.E;
                Key.E = temp;

                stopwatch.Start();
                result = WienerAttack(Key.E, Key.N, MSG);
                AddElapsedTime("", times, stopwatch);
                showTimeElapsed(times);

                wl(" результат атаки:");
                wl(" исходный параметр E: " + Key.D);
                wl(" полученный знаменатель: " + result);
                break;

            case 4:     // атака повторного шифрования
                Key.GenParams();
                ReplayAttach(Key.N, Key.E, MSG);

                //result = ReplayAttach(new BigInteger("84517"), new BigInteger("397"), new BigInteger("8646"));
                stopwatch.Start();
                result = ReplayAttach(Key.N, Key.E, MSG);
                AddElapsedTime("", times, stopwatch);
                showTimeElapsed(times);

                wl(" результат атаки:");
                wl(" найденное значение: " + result.Item1);
                wl(" количество степеней: " + result.Item2);
                break;

            case 5:     // атака бесключевого чтения
                Key.GenParams();
                BigInteger E2;
                do
                {
                    E2 = BigInteger.ProbablePrime(keylength, new SecureRandom());
                } while (Key.WW.Mod(E2).Equals(0));

                stopwatch.Start();
                result = KeylessAttack(Key.N, Key.E, E2, MSG);
                AddElapsedTime("", times, stopwatch);
                showTimeElapsed(times);

                wl(" результат атаки:");
                wl(" исходный текст: " + MSG);
                wl(" найденное значение: " + result);
                break;

            case 6:
                Key = new CustomRSA(2048);
                Key.GenParams();
                DoAllTheJobWithText(s, Key, cur_data, enc_data, dec_data);
                w("\n\n____________________\n\n");
                // внедрение закладки
                Key.InsertBackdoor();
                DoAllTheJobWithText(s, Key, cur_data, enc_data, dec_data);
                w("\n\n____________________\n\n");
                // проверка закладки
                Key.ExtractKeysFromBackdoor(new RsaKeyParameters(false, Key.N, Key.E));
                DoAllTheJobWithText(s, Key, cur_data, enc_data, dec_data);
                break;

            case 0:

                break;
            }



            /// факторизация Ферма

            /*
             * Key.P = BigInteger.ProbablePrime(keylength, new SecureRandom());
             * Key.Q = Key.P.NextProbablePrime();
             * Key.N = Key.P.Multiply(Key.Q);
             * FermatFactoringMethod(Key.N);
             */

            /// атака Винера

            /*
             * Key.GenParams();
             * BigInteger limitD = BigIntSqrt(BigIntSqrt(Key.N)).Divide(BigInteger.Three);
             * int maxlength = limitD.BitLength;
             * do
             * {
             *  Key.E = BigInteger.ProbablePrime(maxlength - maxlength % 8, new SecureRandom());
             * } while (Key.WW.Mod(Key.E).Equals(0) && limitD.CompareTo(Key.E) != 1);
             * Key.D = Key.E.ModInverse(Key.WW);
             * BigInteger temp = Key.D; Key.D = Key.E; Key.E = temp;
             * WienerAttack(Key.E, Key.N, MSG);
             */

            /// атака повторного шифрования

            /*Key.P = BigInteger.ProbablePrime(keylength, new SecureRandom());
            *  Key.Q = BigInteger.ProbablePrime(keylength, new SecureRandom());*/
            //Key.GenParams();
            //ReplayAttach(Key.N, Key.E, MSG);
            //ReplayAttach(new BigInteger("84517"), new BigInteger("397"), new BigInteger("8646"));

            /// атака бесключевого чтения

            /*Key.GenParams();
             * BigInteger E2;
             * do
             * {
             *  E2 = BigInteger.ProbablePrime(keylength, new SecureRandom());
             * } while (Key.WW.Mod(E2).Equals(0));
             * KeylessAttack(Key.N, Key.E, E2, MSG);*/

            //Key.N = new BigInteger("137759");
            //KeylessAttack(Key.N, new BigInteger("191"), new BigInteger("233"), new BigInteger("1234"));

            //CustomRSA Key = new CustomRSA(2048);

            //DoAllTheJobWithText(s, Key, cur_data, enc_data, dec_data);
            w("\n\n____________________\n\n");



            /*// внедрение закладки
             * Key.InsertBackdoor();
             * DoAllTheJobWithText(s, Key, cur_data, enc_data, dec_data);
             * w("\n\n____________________\n\n");
             * // проверка закладки
             * Key.ExtractKeysFromBackdoor(new RsaKeyParameters(false, Key.N, Key.E));
             * DoAllTheJobWithText(s, Key, cur_data, enc_data, dec_data);
             * w("\n\n____________________\n\n");*/

            Console.ReadKey(false);
        }