-1

I'm writing a program to encrypt data. I created a random IV this way:

byte[] ivBytes = new byte[16];
IvParameterSpec iv = new IvParameterSpec(ivBytes);

And used it for the cipher. Now I want to store this IV in a configuration file so I can transport it to the decrypting function, and for that I need to convert the IV to a string format.

I used byte curIV[] = cipher.getIV(); to get the IV and printed it's value to the console, but when I convert it to string, this way String ivString = new String(curIV);, it doesn't return anything.

Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
Loly
  • 125
  • 2
  • 4
  • 11
  • Hey, what is a IV? – Grim May 12 '18 at 07:50
  • Hello, IV is an Initialization vector and it's transferred as a parameter to the cipher. You can read more here- https://en.wikipedia.org/wiki/Initialization_vector – Loly May 12 '18 at 07:56
  • The byte-array may include non-printable characters - you could use [Arrays.toString](https://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#toString(byte[])) - see this [SO answer](https://stackoverflow.com/a/6463665/6287240) – TmTron May 12 '18 at 07:57
  • But what do you expect it to have? i don't see any code adding any value to the byte array – LenosV May 12 '18 at 07:58
  • 1
    @LenosV The bytearray is initialized to 16x0 in the array. Its a valid IV but not very secure! – Grim May 12 '18 at 07:59
  • You are printing nul chars `\0`, which are one of many invisible chars. Instead, print the bytes as hexadecimal, which will always make sense. – Bohemian May 12 '18 at 08:31

2 Answers2

3

Your code works correctly

The array is initialized with a size of 16, where each of this 16 bytes is a 0.

Now, lets look at the ascii table to find the correct character for 0.

enter image description here

Aha, the character for 0 is character NUL.

If you do a new String(cipher.getIV()); you become a valid String value containing no informations.

How to solve

Simply convert a String of size 16 to bytes.

byte[] ivBytes = "123456789abcdef".getBytes();

Security

Computers are good in calculation but bad in random values. Random values are hard to estimated. That makes random values important for security. That makes the 16x0 byte array a bad idea.

Configuration

Finally you need to store that information to the configuration. Hm, as this character is not readable character its hard to save this to a text-based configuration.

Focusing on security you should not allow 16x0 IVs. So 16x0 IVs must not be able to be stored to the configuration.

Suggestion

Use this instead:

String ivString = "blahblah"; // read from configuration if required
IvParameterSpec iv = new IvParameterSpec(ivString.getBytes());
ivString = new String(iv.getIV()); //write to configuration if required
Grim
  • 1,938
  • 10
  • 56
  • 123
  • So you suggest limiting the bytes in the IV to alphanumeric / printable character values? Wouldn't that reduce the possible combinations from `2^128` to `95^16` ~ `2^112`? – Jiri Tousek May 12 '18 at 08:11
  • @JiriTousek Yes it does reduce (95^16???). The security will be improoved because you are forced to use a `IV > 0`. But it does violates the Single-Version-Of-Truth in this way that it is not clear who defines the value-range of the IV: the Spec or the Impl. – Grim May 12 '18 at 08:23
  • From my point of view, if the spec sais `0` is a valid, atomic, authentic value (so a good value), then I hope impl knows better :D. – Grim May 12 '18 at 08:30
  • The problem was indeed a wrong initialization of the IV, Thanks a lot! – Loly May 12 '18 at 08:37
2
byte[] ivBytes = new byte[16];

This creates an array of 16 bytes initialized to 0. 0x00 is not a printable character (it's a control character), so you might have trouble seeing it printed (either problem in printing or problem with how you view the printed result).

Depending on your needs, you may want to:

  • Print it using Arrays.toString() as suggested by @TmTron (but expect to not see the printed result properly in some programs, you'll need hexa viewer to see it properly)
  • Print it in hexadecimal representation
  • Encode it using Base64
Jiri Tousek
  • 12,211
  • 5
  • 29
  • 43
  • Your recommendations are good. But, the point is it doesn't make sense to call 0x00 any kind of character. Not text is not text. – Tom Blodget May 12 '18 at 11:57