如何将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
这通常是一个两步过程:
- 将数字转换为二进制编码;
- 将二进制编码转换为基于文本的编码。
对于这两个步骤,有多种可能的方案。
对于二进制编码: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。
我在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
这通常是一个两步过程:
- 将数字转换为二进制编码;
- 将二进制编码转换为基于文本的编码。
对于这两个步骤,有多种可能的方案。
对于二进制编码: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。