Как преобразовать зашифрованные числа RSA в текст / символы - PullRequest
1 голос
/ 20 февраля 2020

Я написал шифрование RSA в Java. Я пытаюсь превратить числа, которые он выводит в текст или символы. Например, если я передаю его Hello, я получаю:

23805663430659911910

Однако шифрование RSA онлайн возвращает что-то подобное:

GVom5zCerZ + dmOCE7YAp0F + N3L26L

Я просто хотел бы узнать, как преобразовать мои числа во что-то подобное. Номер, возвращаемый моей системой, BigInteger. Это то, что я пробовал до сих пор:

RSA rsa = new RSA("Hello");
BigInteger cypher_number = rsa.encrypt(); // 23805663430659911910
byte[] cypher_bytes = cypher_number.toByteArray(); // [B@368102c8
String cypher_text = new String(cypher_bytes); // J^��*���

// Now even though cypher_text is J^��*��� I wouldn't care as long as I can turn it back.

byte[] plain_bytes = cypher_text.getBytes(); // [B@6996db8 | Not the same as cypher_bytes but lets keep going.
BigInteger plain_number = new BigInteger(plain_bytes); // 28779359581043512470254837759607478877667261

// plain_number has more than doubled in size compared to cypher_number and won't decrypt properly.

Использование байтов - единственный способ, о котором я могу думать. Может кто-нибудь помочь мне понять, что я должен делать, или если это вообще возможно?

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Обычно это двухэтапный процесс:

  1. преобразование в двоичную кодировку числа;
  2. преобразование двоичной кодировки в кодировку текста.

Для обоих этапов возможны несколько схем.


Для двоичного кодирования: спецификации PKCS # 1 всегда включают в себя такую, которая преобразует число в статического размера целое число , Чтобы быть точным, он описывает число в виде строки со старшим байтом октета без знака без знака. Строка октетов - это не что иное, как байтовый массив.

Теперь BigInteger.toByteArray возвращает строку октетов с прямым порядком байтов в динамическом размере со знаком. Таким образом, вам нужно реализовать возможное изменение размера и удаление начального 00 байта в отдельном методе, который я имею в моем другом посте здесь . К счастью, вернуться к числу гораздо проще, так как реализация Java предоставляет конструктор BigInteger(int sign, byte[] value), который читает число без знака и пропускает начальные нулевые байты.

Наличие строки октетов стандартизированного и статического размера может быть ужасно полезно, поэтому я бы не go для любой другой схемы.


Это оставляет преобразование в и из текста. Для этого вы можете (действительно) использовать класс java.util.Base64, который не требует особых объяснений. Единственное примечание, которое я должен сделать, - это то, что он конвертирует в ASCII byte[] для некоторых методов, поэтому вместо него нужно использовать encodeToString(byte[] src).

Другой метод будет шестнадцатеричным, но так как Java не содержит шестнадцатеричный кодер для байтовых массивов в базовых классах, вместо этого я бы go для базовых 64.

1 голос
/ 20 февраля 2020

Я нашел ответ. Если вы нашли это в поиске ответа, вам просто нужно закодировать числа в Base64.

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

// Encode
BigInteger numbers = new BigInteger("5109763");
byte[] bytes = Base64.getEncoder().encode(numbers.toByteArray());
String encoded = new String(bytes); // Encoded value

// Decode
byte[] decoded_bytes = Base64.getDecoder().decode(encoded.getBytes());
BigInteger numbers_again = new BigInteger(decoded_bytes); // Original numbers
...