views:

852

answers:

5

Hi all,

I'm trying to encrypt some integers in java using java.security and javax.crypto.

The problem seems to be that the Cipher class only encrypts byte arrays. I can't directly convert an integer to a byte string (or can I?). What is the best way to do this?

Should I convert the integer to a string and the string to byte[]? This seems too inefficient.

Does anyone know a quick/easy or efficient way to do it?

Please let me know.

Thanks in advance.

jbu

+11  A: 

You can turn ints into a byte[] using a DataOutputStream, like this:

ByteArrayOutputStream baos = new ByteArrayOutputStream ();
DataOutputStream dos = new DataOutputStream (baos);
dos.writeInt (i);
byte[] data = baos.toByteArray();
// do encryption

Then to decrypt it later:

byte[] decrypted = decrypt (data);
ByteArrayInputStream bais = new ByteArrayInputStream (data);
DataInputStream dis = new DataInputStream (bais);
int j = dis.readInt();
jodonnell
+3  A: 

I have found the following code that may help you, since Integer in Java is always 4 bytes long.

public static byte[] intToFourBytes(int i, boolean bigEndian) {  
    if (bigEndian) {  
        byte[] data = new byte[4];  
        data[3] = (byte) (i & 0xFF);  
        data[2] = (byte) ((i >> 8) & 0xFF);  
        data[1] = (byte) ((i >> 16) & 0xFF);  
        data[0] = (byte) ((i >> 24) & 0xFF);  
        return data;  

    } else {  
        byte[] data = new byte[4];  
        data[0] = (byte) (i & 0xFF);  
        data[1] = (byte) ((i >> 8) & 0xFF);  
        data[2] = (byte) ((i >> 16) & 0xFF);  
        data[3] = (byte) ((i >> 24) & 0xFF);  
        return data;  
    }  
}

You can find more information about the bigEndian parameter here: http://en.wikipedia.org/wiki/Endianness

Paulo Guedes
+9  A: 

You can also use BigInteger for conversion:

 BigInteger.valueOf(integer).toByteArray();
asalamon74
you're creating an un needed intermediate string object in this process.
OscarRyz
+5  A: 

Just use NIO. It's designed for this specific purpose. ByteBuffer and IntBuffer will do what you need quickly, efficiently, and elegantly. It'll handle big/little endian conversion, "direct" buffers for high performance IO, and you can even mix data types into the byte buffer.

Convert integers into bytes:

ByteBuffer bbuffer = ByteBuffer.allocate(4*theIntArray.length);
IntBuffer ibuffer = bbuffer.asIntBuffer(); //wrapper--doesn't allocate more memory
ibuffer.put(theIntArray);                  //add your int's here; can use 
                                           //array if you want
byte[] rawBytes = bbuffer.array();         //returns array backed by bbuffer--
                                           //i.e. *doesn't* allocate more memory

Convert bytes into integers:

ByteBuffer bbuffer = ByteBuffer.wrap(rawBytes);
IntBuffer ibuffer = bbuffer.asIntBuffer();
while(ibuffer.hasRemaining())
   System.out.println(ibuffer.get());      //also has bulk operators
James Schek
A: 

create a 4-byte array and copy the int to the array in 4 steps, with bitwise ANDs and bitshifting, like Paulo said.

But remember that block algorithms such as AES and DES work with 8 or 16 byte blocks so you will need to pad the array to what the algorithm needs. Maybe leave the first 4 bytes of an 8-byte array as 0's, and the other 4 bytes contain the integer.

Chochos