Алгоритм кодирования RSA Java - PullRequest
       54

Алгоритм кодирования RSA Java

0 голосов
/ 28 сентября 2018

Итак, я пытаюсь создать алгоритм RSA с нуля.

До сих пор я успешно создал возможность выбора двух простых чисел (которые в моем текущем примере равны 11 и 13). Затем я вычисляю N, используя px q. Что дает мне 143.

Затем я перехожу к моему public BigInteger findZ() методу, который вычисляет ϕ, который равен (p-1) (q-1).

Используя это недавно вычисленное ϕ, я хочу найти число, иливместо этого создайте переменную e, которая следует 1 <(e) <ϕ, или просто gcd (e, ϕ) = 1. Таким образом, я изначально установил temp равным моей постоянной ONE (которая равна единице) + 1, чтобы удовлетворить диапазон.Однако после попыток непрерывной отладки цикл никогда не находит значение с GCD, равным единице, которое я создал для представления константы, поскольку мне необходимо использовать BigInteger. Есть ли причина для этого? </p>

Вот мой код.

import java.math.BigInteger;

public class RSA 
{
//Intialize the variables.

private BigInteger p;
private BigInteger q;
private BigInteger n;
private BigInteger z;

final private BigInteger ONE = BigInteger.valueOf(1);


public BigInteger getP()
{
    return p;
}

public BigInteger getQ()
{
    return q;
}

//Computes N, which is just p*q.
public BigInteger findN()
{

    n = p.multiply(q);


    return p.multiply(q);
}


public BigInteger findZ()
{
    long pMinusOne = p.intValue() - 1;
    long qMinusOne = q.intValue() - 1;


    z = BigInteger.valueOf(pMinusOne * qMinusOne);

    return z;
}


public BigInteger getE()
{
     int temp = ONE.intValue() + 1;

     BigInteger GCD = BigInteger.valueOf(temp);

     while (GCD.gcd(z).compareTo(ONE) != 0)
     {
         temp++;
     }



    e = BigInteger.valueOf(temp);

    return e;
}

}

Любая помощь приветствуется.

Спасибо!

1 Ответ

0 голосов
/ 28 сентября 2018

Так как вы попросили любую помощь, я отвечу на ваш вопрос и дам другие советы.

Как получить e

Один совет - использовать equals() вместо compareTo(), когда вы просто проверяете равенство.Иногда это может уменьшить объем выполняемой работы, а также его легче читать.

Самая большая ошибка в вашем коде заключается в том, что temp используется для установки исходного значения GCD, но , который не связывает temp с GCD .Они остаются отключенными.Если вы измените temp позже, GCD не узнает об этом и не изменится.Вам нужно добавить один к GCD напрямую.Вот пример кода:

BigInteger e = BigInteger.valueOf(3);
while (! phi.gcd(e).equals(BigInteger.ONE)) {
    e = e.add(BigInteger.ONE);
}

Просмотрите методы BigInteger

Получите представление о том, что вы можете легко сделать с BigInteger, используя вашу любимую поисковую систему ипоиск BigInteger 8 API.8 для версии Java, которую вы используете, так что это может измениться.API предназначен для списка методов.

В самом начале результатов поиска вы должны найти эту страницу API .BigInteger имеет много хороших и удобных методов, так что проверьте их.У него даже есть конструктор, который даст вам BigInteger любого размера, который вы хотите, который, скорее всего, будет простым, что хорошо для генерации простых чисел для нового случайного ключа RSA.

Использование BigInteger Встроенные константы

Не создавайте заново следующие константы (которые показаны на странице API выше):

  • BigInteger.ZERO
  • BigInteger.ONE
  • BigInteger.TEN

Никогда не конвертируйте BigInteger в long, если вы не уверены, что оно будет соответствовать

Вы конвертируете BigInteger s до long, что является плохой идеей, поскольку существует множество BigInteger, которые не помещаются в long, давая вам неправильные результаты.Для правильности (что важнее скорости), делайте арифметику напрямую с BigInteger s .

Вы также часто используете intValue(), когда получаете long.Используйте longValueExact().В этом отношении используйте intValueExact(), когда вы получаете int.

Итак, чтобы вычислить ϕ:

BigInteger pMinusOne = p.subtract(BigInteger.ONE);
BigInteger qMinusOne = q.subtract(BigInteger.ONE);

BigInteger phi = pMinusOne.multiply(qMinusOne);

Теперь вы знаете, что это даст правильные результаты, дажедля больших BigInteger с.Это также не так сложно для чтения, что хорошо для поддержки кода позже.

Что хранить

Вы также должны хранить только n и e d , но только если это закрытый ключ) Никогда store p , q или ϕ с RSA, потому что они позволяют вам легко определить закрытый ключ из открытого ключа.

В общем, не рассчитывайте в getZZZ методах

Вы должны выяснить n и e d , но только если это закрытый ключ) в методе (ах) конструктора и сохраняют только те, которые находятся в переменных экземпляра.Затем у вас может быть метод getN() и getE() для получения предварительно вычисленных переменных экземпляра.Например (и вам не нужно использовать этот код, это просто для того, чтобы дать представление):

public class RSA {
    private final BigInteger n;
    private final BigInteger e;
    private final BigInteger d;

    public RSA(final BigInteger p, final BigInteger q) {
        this.n = p.multiply(q);

        // Calculate phi
        final BigInteger pMinusOne = p.subtract(BigInteger.ONE);
        final BigInteger qMinusOne = q.subtract(BigInteger.ONE);
        final BigInteger phi = pMinusOne.multiply(qMinusOne);

        // Calculate e
        BigInteger e = BigInteger.valueOf(3L);
        while (! phi.gcd(e).equals(BigInteger.ONE)) {
            e = e.add(BigInteger.ONE);
        }
        this.e = e;

        // Calculate d
        this.d = e.modInverse(phi);
    }

    public BigInteger getN() {
        return n;
    }

    public BigInteger getE() {
        return e;
    }

    public BigInteger getD() {
        return d;
    }
}
...