如何将RSA加密数字转换成text/characters

How to convert RSA encrypted numbers into text/characters

我在Java写了一个RSA加密。我正在尝试将它输出的数字转换为文本或字符。例如,如果我喂它 Hello 我得到:

23805663430659911910

然而,在线 RSA 加密 return 大意是这样的:

GVom5zCerZ+dmOCE7YAp0F+N3L26L

我只想知道如何将我的数字转换成类似的东西。我的系统输入的数字 return 是 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.

使用字节是我能想到的唯一方法。有人可以帮我理解我应该做什么,或者这是否可能?

我找到了答案。如果您发现这个正在寻找答案,您只需要将数字编码为 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

这通常是一个两步过程:

  1. 将数字转换为二进制编码;
  2. 将二进制编码转换为基于文本的编码。

对于这两个步骤,有多种可能的方案。


对于二进制编码:PKCS#1 规范始终包括将数字转换为静态大小 整数的规范。准确地说,它将数字描述为一个静态大小的、无符号的、大端八位字节串。一个八位字节串只不过是一个字节数组。

现在,BigInteger.toByteArray returns 一个动态大小的、有符号的、大端八位字节字符串。所以你需要在一个单独的方法中实现可能的调整大小和删除初始 00 字节,我在另一个 post here 中有。幸运的是,回到数字要容易得多,因为 Java 实现提供了一个 BigInteger(int sign, byte[] value) 构造函数,该构造函数读取无符号数字并跳过前导零字节。

拥有标准化和静态大小的八位字节字符串可能非常有用,所以我不会选择任何其他方案。


这样就剩下了文本之间的转换。为此,您可以(确实)使用 java.util.Base64 class,这不需要太多解释。我必须注意的唯一一点是,对于某些方法,它会转换为 ASCII byte[],因此您需要改用 encodeToString(byte[] src)

另一种方法是十六进制,但由于 Java 不包含 base classes 中字节数组的十六进制编码器,我会改用 base 64。