RSA шифрование кириллицы

137
21 января 2018, 04:04

Исходная реализация алгоритма взята отсюда. Для простоты есть 2 класса сам алгоритм и Main (psvm):

import java.math.BigInteger;
import java.security.SecureRandom;
public class RSA {
    private final static BigInteger one = new BigInteger("1");
    private final static SecureRandom random = new SecureRandom();
    private BigInteger privateKey;
    private BigInteger publicKey;
    private BigInteger modulus;
    RSA(int N) {
        BigInteger p = BigInteger.probablePrime(N / 2, random);
        BigInteger q = BigInteger.probablePrime(N / 2, random);
        BigInteger phi = (p.subtract(one)).multiply(q.subtract(one));
        modulus = p.multiply(q);
        publicKey = new BigInteger("65537");     // common value in practice = 2^16 + 1
        privateKey = publicKey.modInverse(phi);
    }
    BigInteger encrypt(BigInteger message) {
        return message.modPow(publicKey, modulus);
    }
    BigInteger decrypt(BigInteger encrypted) {
        return encrypted.modPow(privateKey, modulus);
    }
}

и

import java.math.BigInteger;
public class Main {
    public static void main(String[] args) {
        int N = 1024; //количество бит для генерации RSA ключей
        RSA rsa = new RSA(N);
        //создаем сообщение в BigInteger формате
        BigInteger message = new BigInteger("Привет Мир! I love you!".getBytes());
        //далее, зашифровываем секретное сообщение
        BigInteger encryptMessage = rsa.encrypt(message);
        // Расшифровываем зашифрованное сообщение
        BigInteger decryptMessage = rsa.decrypt(encryptMessage);
        /* Выводим наш результат на экран */
        System.out.println(new String(decryptMessage.toByteArray()));
    }
}

Когда шифруются ASCII-символы, то все норм. Но если первая буква сообщения в байтовом представлении представляет собой отрицательное число (любая буква кириллицы, например), то и весь BigInteger, который представляет это секретное сообщение, будет отрицательным и результат будет неверным.

Я обошел это, добавляя один байт впереди при шифровании и не учитываю его в расшифрованном BigInteger-e. Но это похоже на костыль, мне не нравится, хочется чтобы красиво было.

Какие есть мысли?

Answer 1

Используйте другой конструктор:

BigInteger x = new BigInteger(1, new byte[] { -100 });

Получается x = 156

А вообще, если ваш пример не учебный, криптографию лучше не писать самому, а использовать готовые имплементации.

READ ALSO
Как правильно инициализировать переменные объекта в Java?

Как правильно инициализировать переменные объекта в Java?

Прошу уточнить какой вариант инициализации является наиболее хорошей практикойЕсли ни один из них не является хорошей, то прошу привести...

167
Изменение цвета линий в ListView

Изменение цвета линий в ListView

Как изменить только цвет линий(полосок) в ListView?

197
Создание файла Java

Создание файла Java

Здравствуйте, как создать файл на диске С? Когда делаю на D, все работаетКогда изменяю D на С ничего не происходит

211
ArrayDeque хранит только ссылки на объекты?

ArrayDeque хранит только ссылки на объекты?

Я пытаюсь сделать стек из arraylist'ов, но созданный мною хранит только ссылку на объект, который в него добавили, а я хочу, чтобы он хранил сам...

146