How to convert RSA encrypted numbers into text/characters

MagneticFlux :

I wrote a RSA encryption in Java. I am trying to turn the numbers that it outputs into text or characters. For example if I feed it Hello I get:

23805663430659911910

However, online RSA encryptions return something to the effect of this:

GVom5zCerZ+dmOCE7YAp0F+N3L26L

I would just like to know how to convert my numbers into something similar. The number returned by my system is a BigInteger. This is what I've tried so far:

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.

Using bytes it the only way I can think of. Can someone please help me understand what I'm supposed to be doing or if it's even possible?

Maarten Bodewes :

This is generally a 2-step process:

  1. convert to binary encoding of the number;
  2. convert the binary encoding to a text base encoding.

For both steps there are multiple schemes possible.


For binary encoding: the PKCS#1 specifications have always included one that converts the number to a statically sized integer. To be precise, it describes the number into a statically sized, unsigned, big endian octet string. An octet string is nothing but a byte array.

Now, BigInteger.toByteArray returns a dynamically sized, signed, big endian octet string. So you need to implement the possible resizing and removal of initial 00 byte in a separate method, which I have at my other post here. Fortunately going back to a number is much easier as the Java implementation provides a BigInteger(int sign, byte[] value) constructor that reads in an unsigned number and skips leading zero bytes.

Having a standardized and statically sized octet string can be terribly useful, so I would not go for any other scheme.


This leaves the conversion to and from text. For that you can (indeed) use the java.util.Base64 class, which doesn't need much explaining. The only note that I must make is that it converts to an ASCII byte[] for some of the methods, so you need to use the encodeToString(byte[] src) instead.

Another method would be hexadecimals, but since Java doesn't contain a hex encoder for byte arrays in the base classes, I'd go for base 64 instead.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=420322&siteId=1