2015-03-05 6 views
0

Я работаю над Java-приложением, которое требует использования двух ключей , сгенерированных из разных строк для шифрования и дешифрования. Один Строка поступает от пользователя, а другой - мастер-ключ. Я посмотрел на net и нашел несколько ссылок на него. Мне бы очень понравилась помощь в знании того, как это реализовать. Я покажу, что у меня есть.Создание и использование двух ключей для шифрования и дешифрования в Java

Так как вы можете видеть из кода, я использовал некоторый код из другого столбца stackoverflow и немного изменил его. Я просто не знаю, как сгенерировать 2 ключа из 2 строк и откуда я могу получить SecretKey desKey, используемый для дешифрования.

Код:

public class Encryption { 

public void doStuff() { 

    String plaintext = "abc"; 

    SecretKey k1 = generateDESkey(); 
    SecretKey k2 = generateDESkey(); 


    String firstEncryption = desEncryption(plaintext, k1); 
    String decryption = desDecryption(firstEncryption, k2); 
    String secondEncryption = desEncryption(decryption, k1); 

    System.out.println(firstEncryption); 
    System.out.println(decryption); 
    System.out.println(secondEncryption); 
} 

public static SecretKey generateDESkey() { 
    KeyGenerator keyGen = null; 
    try { 
     keyGen = KeyGenerator.getInstance("DESede"); 
    } catch (NoSuchAlgorithmException ex) { 
     Logger.getLogger(Test.class 
       .getName()).log(Level.SEVERE, null, ex); 
    } 
    try { 
     assert keyGen != null; 
     keyGen.init(112); // key length 56 
     return keyGen.generateKey(); 
    } catch (NullPointerException ex){ 
     return null; 
    } 
} 


public static String desEncryption(String strToEncrypt, SecretKey desKey) { 
    try { 
     Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, desKey); 
     return Base64.encode(cipher.doFinal(strToEncrypt.getBytes())); 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | 
      IllegalBlockSizeException | BadPaddingException | 
      InvalidKeyException ex) { 
     Logger.getLogger(Test.class 
       .getName()).log(Level.SEVERE, null, ex); 
    } 
    return null; 
} 


public static String desDecryption(String strToDecrypt, SecretKey desKey) { 
    try { 
     Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, desKey); 
     return new String(cipher.doFinal(Base64.decode(strToDecrypt))); 

    } catch (NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException 
      | InvalidKeyException | NoSuchPaddingException ex) { 
     Logger.getLogger(Test.class 
       .getName()).log(Level.SEVERE, null, ex); 
    } 
    return null; 
} 

} 

Если есть какие-либо путаницы или сомнений по этому поводу. Пожалуйста, дайте мне знать.

+0

В чем проблема с текущим кодом? Любые исключения, такие как BadPaddingException? –

+0

@ArtjomB. Я изменил его на DESede, но как я могу сгенерировать ключи из String для DESede? Плюс я смотрю, как я могу расшифровать, используя комбинацию из двух клавиш? –

+0

Кроме того, кажется, вы делаете тройной Triple DES. Это нужно? –

ответ

3

Ответьте на код прежде чем он был изменен.

Вы пытаетесь сделать DESede только с двумя клавишами вместо трех.

Возможно, это работает, но не так, как вы писали. Проблема заключается в дополнении. На втором этапе вы пытаетесь расшифровать зашифрованный текст другим ключом, чем с тем, что он был зашифрован, поэтому дешифровка завершится не более 255 из 256 раз, поскольку заполнение будет неправильным (также потому, что вы используете кодировку Base64, где она не обязательно).

Если вы действительно хотите это сделать, вам придется расшифровывать без заполнения и без кодировки Base64. Хорошо, что незашифрованный зашифрованный текст уже кратен блокам, поэтому вы не можете использовать "DES/ECB/NoPadding".

public static void main(String[] args) { 
    // First I would like to create keys by giving Strings 
    SecretKey k1 = generateDESkey(); 
    SecretKey k2 = generateDESkey(); 

    // encryption 
    byte[] firstEncryption = desEncryption("plaintext".getBytes("UTF-8"), k1, false); 
    byte[] decryption = desDecryption(firstEncryption, k2, true); 
    byte[] secondEncryption = desEncryption(decryption, k1, true); 

    // decryption 
    byte[] firstDecryption = desDecryption(secondEncryption, k1, true); 
    byte[] encryption = desEncryption(firstDecryption, k2, true); 
    byte[] secondDecryption = desDecryption(encryption, k1, false); 

    System.out.println(new String(secondDecryption)); // plaintext 
} 

public static byte[] desEncryption(byte[] strToEncrypt, SecretKey desKey, boolean noPadding) { 
    try { 
     Cipher cipher = Cipher.getInstance(noPadding ? "DES/ECB/NoPadding" : "DES/ECB/PKCS5Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, desKey); 
     return cipher.doFinal(strToEncrypt); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    return null; 
} 

public static byte[] desDecryption(byte[] strToDecrypt, SecretKey desKey, boolean noPadding) { 
    try { 
     Cipher cipher = Cipher.getInstance(noPadding ? "DES/ECB/NoPadding" : "DES/ECB/PKCS5Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, desKey); 
     return cipher.doFinal(strToDecrypt); 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 
    return null; 
} 

Это фактически эквивалентна реализация DESede с двумя ключами, когда общий ключ строятся таким образом:

SecretKey k1 = generateDESkey(); 
SecretKey k2 = generateDESkey(); 

byte[] edeKeyBytes = new byte[24]; 
System.arraycopy(k1.getEncoded(), 0, edeKeyBytes, 0, 8); 
System.arraycopy(k2.getEncoded(), 0, edeKeyBytes, 8, 8); 
System.arraycopy(k1.getEncoded(), 0, edeKeyBytes, 16, 8); 

edeKey = new SecretKeySpec(edeKeyBytes, "DESede"); 

Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding"); 
cipher.init(Cipher.ENCRYPT_MODE, edeKey); 

System.out.println(Base64.encode(cipher.doFinal("plaintext".getBytes("UTF-8")))); 

DESede использует три ключа, которые мы будем называть k1, k2 и k3. Все они объединены в один байтовый массив. В вашем случае k1 используется во второй раз вместо k3.

+0

Спасибо за ваш ответ, это очень помогает. Как вы генерируете ключи из простой строки, я не видел этого в вашем коде. –

+0

Я этого не делаю. Если строки не являются ключевым материалом, а скорее каким-то паролем, то вы можете использовать что-то вроде PBKDF2 для вывода ключа из строки. –

+0

Я проверю его, но если у вас есть пример, как получить ключ от String, пожалуйста, дайте мне знать. –