2014-11-28 4 views
0

Я шифрую данные, используя тройной DES. Он отлично работает, но у меня есть вопрос.Где находится IV в Triple DES?

Где я могу увидеть вектор инициализации (IV)?

Это 3-й прием с BASE64Decoder.

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 
import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.SecretKey; 
import javax.crypto.spec.SecretKeySpec; 
import sun.misc.BASE64Decoder; 
import sun.misc.BASE64Encoder; 

public class Crypter { 

    Cipher ecipher; 
    Cipher dcipher; 

    Crypter(String as_Phrase) 
      throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException { 
     this.ecipher = Cipher.getInstance("DESede"); 
     this.dcipher = Cipher.getInstance("DESede"); 
     this.ecipher.init(1, getSecretKey(as_Phrase)); 
     this.dcipher.init(2, getSecretKey(as_Phrase)); 

    } 

    public String encrypt(String as_valueToEncrypt) 
      throws BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, IOException { 
     byte[] lbarr_utf8 = as_valueToEncrypt.getBytes("UTF8"); 
     byte[] lbarr_enc = this.ecipher.doFinal(lbarr_utf8); 

     return new BASE64Encoder().encode(lbarr_enc); 
    } 

    public String decrypt(String as_valueToDecrypt) 
      throws BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, IOException { 
     byte[] lbarr_enc = new BASE64Decoder().decodeBuffer(as_valueToDecrypt); 

     byte[] lbarr_utf8 = this.dcipher.doFinal(lbarr_enc); 

     return new String(lbarr_utf8, "UTF8"); 
    } 

    private SecretKey getSecretKey(String as_Phrase) 
      throws UnsupportedEncodingException { 
     return new SecretKeySpec(as_Phrase.getBytes("UTF8"), "DESede"); 
    } 
} 
+0

Вам никогда не приходило в голову смотреть на Javadocs for Cipher? –

+0

Достаточно пожалуйста с сахаром сверху, пожалуйста, используйте константы, если они были определены. Определите свои собственные, если они не имеют и используют перечисления в новых API. 'Cipher.ENCRYPT_MODE' намного понятнее, чем' 1' в методе 'init', вы согласны? –

ответ

4

Вы можете получить IV от шифра:

ecipher.getIV(); 

Проблема заключается в том, что IV генерируется во время init. Поскольку у вас init в конструкторе вы столкнулись с проблемой использования одного и того же IV для каждого шифрования разных зашифрованных текстов. Всегда лучше создавать новый Cipher и инициализировать его для каждой операции шифрования и дешифрования отдельно.

Вы используете шифр DESede, который на самом деле DESede/ECB/PKCS5Padding. Обратите внимание, что режим ECB, который не использует IV. Таким образом, вышеуказанный вызов возвращает null. Хотя это режим по умолчанию, он не рекомендуется. Безопаснее использовать DESede/CBC/PKCS5Padding, который фактически использует IV.

Итак, когда вы расшифровать в режиме CBC вам нужно передать, что IV в:

dcipher.init(2, new SecretKeySpec(key, "DESede"), new IvParameterSpec(ecipher.getIV())); 

Чтобы уменьшить нагрузку прохождения IV вокруг можно затем добавить IV к передней части шифротекста перед кодированием его и отрезать его перед расшифровкой зашифрованного текста. DES - это 64-разрядный шифр, поэтому ваш IV будет длиной 8 байтов.

1

Cipher имеет getIV() метод, который возвращает вектор инициализации.

+0

Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий ниже своего сообщения - вы всегда можете прокомментировать свои собственные сообщения, и как только у вас будет достаточно [репутации] (http://stackoverflow.com/help/whats-reputation), вы будете быть в состоянии [прокомментировать любое сообщение] (http://stackoverflow.com/help/privileges/comment). –

+2

@KickButtowski это ответ, вопрос задает вопрос о том, как получить IV, этот ответ дает метод, который делает именно это. –

+0

Это ответ, но это не очень хороший ответ, так как код использует '' DESede'' без указания режима. В (почти) все время работы это будет по умолчанию режим ECB, который вообще не использует IV. –

Смежные вопросы