AES Key encoded byte [] for string and back to byte []

In a similar question, "Convert byte [] to string and then back to byte []" , they say, does not byte [] to Convert strings and back, which is similar to most cases, mostly when you don't know which encoding is used.

But in my case, I'm trying to save javax.crypto.SecretKey data in the database and restore it after.

The interface provides the getEncoded () method, which returns key data encoded as byte [], and with another class I can use this byte [] to restore the key.

So the question is, how to write key bytes as String, and then return byte [] to restore the key?

+4
source share
4 answers

javax.crypto.SecretKey is binary data, so you cannot convert it directly to a string. You can encode it as the sixth line or in Base64.

See Apache Commons Codec .

Update. If you do not want to depend on third-party libraries (and cannot / do not want to store simple binary data, as John suggests), you can do some ad-hoc encoding, for example, after the erickson sentence:

 public static String bytesToString(byte[] b) { byte[] b2 = new byte[b.length + 1]; b2[0] = 1; System.arraycopy(b, 0, b2, 1, b.length); return new BigInteger(b2).toString(36); } public static byte[] stringToBytes(String s) { byte[] b2 = new BigInteger(s, 36).toByteArray(); return Arrays.copyOfRange(b2, 1, b2.length); } 

It is rather ugly, non-standard and not optimal (in terms of output). But he is also very small, correct and has no dependencies; this can be practical, especially if your data is small.

Updated: I replaced Character.MAX_RADIX with a literal value (36), following GregS comment. It may seem less elegant, but actually more secure. (You can also use 32 or 16).

+6
source

Use base-64 encoding to safely convert arbitrary binary data to and from string.

The Apache Commons Codec library provides code for this, just like the others. (I'm not terribly interested in the Apache Commons Codec API, admittedly. I don't know any other libraries with this functionality, but I'm sure they exist.)

EDIT: This project provides a single file for fast encoding and decoding and has subroutine signatures as well as many additional options if you need them.

Alternatively, if you need to store it in a database, why not just use the appropriate binary data field (Image / Blob or something else for your database) instead of storing it as a string in the first place?

+3
source

What about encoding as a number instead of a character string? It is not as compact as Base-64, but you can leave Apache Commons.

 /* Store the key. */ BigInteger n = new BigInteger(1, key.getEncoded()); /* Store as NUMBER, or … */ String s = n.toString(32); /* … store as VARCHAR. */ /* Reconstruct the key (may need to pad most significant bytes with zero). */ BigInteger n = new BigInteger(s); /* Load from VARCHAR, or … */ byte[] raw = n.toByte(); /* … load from NUMBER. */ byte[] original = new byte[16]; System.arraycopy(raw, 0, original, 16 - raw.length, raw.length); 
+1
source

You cannot use the constructor String: String (byte [] data, String charsetName), as in:

 byte[] data=new byte[1024]; String key=new String(data,"UTF-8"); 

and then you can do:

 String key="mymostsecretaeskey"; byte[] data=key.getBytes("UTF-8"); 
0
source

Source: https://habr.com/ru/post/1310994/


All Articles