nana
nana

Reputation: 79

How to change the array size from 20 Byte the output of SHA-1 to fit the IV 16 Byte in AES encryptopn

I need to implement AES-CBC encryption algorithm, but the example that I have creates the initialize IV manually:

//initialize IV  manually

byte[] ivBytes = new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

The AES-CBC that I have:

    package xxxx;
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.IvParameterSpec; 
    import javax.crypto.spec.SecretKeySpec;
    public class AES_CBC
    {
        public static void main(String[] args)
        {
            try
            {
                    //Lookup a key generator for the AES cipher
                        KeyGenerator kg = KeyGenerator.getInstance("AES");
                SecretKey key = kg.generateKey();
                SecretKeySpec keySpec = new
                        SecretKeySpec(key.getEncoded(), "AES");     
              //Lookup an instance of a AES cipher
               Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

      //initialize IV  manually
byte[] ivBytes = new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
            //create IvParameterSpecobject
              IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);     

            //Initialize the cipher using the secter key

        cipher.init(Cipher.ENCRYPT_MODE, keySpec,ivSpec);

           //Message to encrypt
             String plainText = "This is a secret!";

             //Sequence of byte to encrypt 
             //Encrypt the message      
            byte[] cipherText = cipher.doFinal(plainText.getBytes());

                System.out.println("Resulting Cipher Text:\n");
                for(int i=0;i<cipherText.length;i++)
                {
                System.out.print(cipherText[i] + " ");
                }
                System.out.println("");
                        } catch (Exception e)
            {
                e.printStackTrace();
            } } }

Instead of setting IV manually, I would like to use the output of SHA-1 as the initialize IV, as each time I have different integer value I use SHA-1 to get fixed length and reuse it as initialize IV in AES, for example:

input : 10
digest : b1d5781111d84f7b3fe45a0852e59758cd7a87e5

So, AES code needs 16Byte, and SHA-1 produces 20 Bytes, how can I transfer 20B to be fitted as 16 Byte in AES code?

How to reuse :b1d5781111d84f7b3fe45a0852e59758cd7a87e5 instead of 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

Upvotes: 0

Views: 91

Answers (1)

rustyx
rustyx

Reputation: 85501

It's unclear what you mean by "use the output of SHA-1 as the initialize IV". What information do you hash? It sounds like security through obscurity.

A good IV should be absolutely random and unpredictable in order to be secure.

Just get random bytes from a SecureRandom to use as IV:

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

    SecureRandom rnd = new SecureRandom();
    byte[] iv = new byte[cipher.getBlockSize()];
    rnd.nextBytes(iv);
    IvParameterSpec ivParams = new IvParameterSpec(iv);

    cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), ivParams);

    byte[] ciphertext = cipher.doFinal(input.getBytes());

Then store the generated IV in the encrypted output together with the ciphertext.

During decryption, first read in the IV, then the ciphertext, and then decrypt.

Upvotes: 1

Related Questions