Как изменить размер массива с 20 байт на выходе SHA-1, чтобы он соответствовал 16-байтовому IV в AES encryptopn - PullRequest
0 голосов
/ 17 октября 2018

Мне нужно реализовать алгоритм шифрования AES-CBC, но у меня есть пример, который создает IV инициализации вручную:

//initialize IV  manually

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

AES-CBC, который у меня есть:

    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();
            } } }

Вместо установки IV вручную, я хотел бы использовать выход SHA-1 в качестве инициализирующего IV, поскольку каждый раз, когда у меня есть другое целочисленное значение, я использую SHA-1, чтобы получить фиксированную длину и повторно использовать его в качестве инициализирующего IV в AES, дляпример:

input : 10
digest : b1d5781111d84f7b3fe45a0852e59758cd7a87e5

Итак, для кода AES требуется 16 байт, а SHA-1 выдает 20 байтов, как я могу передать 20B, чтобы соответствовать 16 байтам в коде AES?

Как использовать повторно: b1d5781111d84f7b3fe45a0852e59758cd7a87e5 вместо 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00

1 Ответ

0 голосов
/ 18 октября 2018

Непонятно, что вы подразумеваете под ", используйте выход SHA-1 в качестве инициализированной IV ".Какую информацию вы хешируете?Это звучит как безопасность через неизвестность.

Хороший IV должен быть абсолютно случайным и непредсказуемым, чтобы быть в безопасности.

Просто получите случайные байты из SecureRandom для использования в качестве 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());

Затем сохраните сгенерированный IV в зашифрованном виде вместе с зашифрованным текстом.

Во время дешифрования сначала прочитайте IV, затем зашифрованный текст, а затем расшифруйте.

...