01 января 2008

Алгоритм Des. Симметрическое шифрование в java

Симметрическое шифрование - способ шифрования, в котором для (за)шифрования и расшифрования применяется один и тот же криптографический ключ.
Рассмотрим реализацию симметрического шифрования в java на примере алгоритма DES. В первую очередь нам понадобится класс javax.crypto.Cipher , который реализует базовые функции популярных криптографических алгоритомов шифрования. Для создания экземпляра такого класса используется статистический метод Cipher.getInstance , который в качестве параметра получает имя криптографического алгоритма шифрования. В нашем случае:

Cipher chr = Cipher.getInstance("DES");

Следующим шагом будет инициализация экземпляра класса и указание каком режиме он будет работать:
в режиме шифрования chr.init(Cipher.ENCRYPT_MODE, key); - , или расщифрования -
chr.init(Cipher.DECRYPT_MODE, key); .

Как видно, появился новый неизвесный параметр: key - это 56 битный ключ алгоритма DES. Данный параметр имеет тип javax.crypto.SecretKey и может быть создан с помощью класса

javax.crypto.KeyGenerator.
SecretKey key = KeyGenerator.getInstance("DES").generateKey();

Шифрование или расшифрование выполняет функция doFinal класса Cipher, которая на входе получает масив байт и возвращает также масив байт, но уже соответственно преобразованных. Что именно (шифрование или расшифрование) будет выполнять функция зависит от того что было указанно в первом параметре функции инициализации init().

Итак из всего выше сказанного можно скомпоновать небольшой класс. Класс по работе скриптографическим алгоритмом шифрования DES. К классу прилагается функция main, для того что-бы проверить правильностб работы созданных функций.


import javax.crypto.*;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
* Класс реализующий работу с алгоритмом шифрования DES
* @author Rumoku
*/
class DesEncrypter {
Cipher ecipher;
Cipher dcipher;

/**
* Конструктор
* @param key секретный ключ алгоритма DES. Экземпляр класса SecretKey
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
*/
public DesEncrypter(SecretKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
ecipher = Cipher.getInstance("DES");
dcipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
dcipher.init(Cipher.DECRYPT_MODE, key);
}

/**
* Функция шифровнаия
* @param str строка открытого текста
* @return зашифрованная строка в формате Base64
*/
public String encrypt(String str) throws UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
return new sun.misc.BASE64Encoder().encode(enc);
}

/**
* Функция расшифрования
* @param str зашифрованная строка в формате Base64
* @return расшифрованная строка
*/
public String decrypt(String str) throws IOException, IllegalBlockSizeException, BadPaddingException {
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF8");
}
/**
* Функция для проверки правильности работі класса
*/
public static void main(String[] s) throws IllegalBlockSizeException, BadPaddingException, IOException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException{
SecretKey key=null;
key = KeyGenerator.getInstance("DES").generateKey();
DesEncrypter encrypter = new DesEncrypter(key);
String OStr1="simple string";
String SStr = encrypter.encrypt(OStr1);
String OStr2 = encrypter.decrypt(SStr);
System.out.println("Open String:"+OStr1+
"\nAfter encripting: "+SStr+"\nAfter decripting: "+OStr2);
}
}




6 комментариев:

Unknown комментирует...

Спасибо статья хорошая и пример кода тоже сам когда то писал этот алгоритм(для учёбы) но только на С++, а тут всё здорово даже вспоминать не пришлось как писать надо

stacktrace комментирует...

А как можно записать этот SecretKey в строку? Мне нужно его сохранять в базе.

S комментирует...

Спасибо за статью. Помогла разобраться с темой.

Slavig комментирует...

Да пацаны круто. Я уже был запарился.
Строки это зло для байтовых операций.

Patronus комментирует...

/**
*
* @author javadb.com
*/
public class Main {

/**
* Example method for converting a byte to a String.
*/
public void convertByteToString() {

byte b = 65;

//Using the static toString method of the Byte class
System.out.println(Byte.toString(b));

//Using simple concatenation with an empty String
System.out.println(b + "");

//Creating a byte array and passing it to the String constructor
System.out.println(new String(new byte[] {b}));

}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new Main().convertByteToString();
}
}
взято с сайта : http://www.javadb.com/convert-byte-to-string

alecss комментирует...

ох, не понял я принципа. Получается, чтобы расшифровать надо где-то хранить сгенерированный при шифровании SecretKey ?
Мне надо зашифровать текст. Положить зашифрованный текст в файл.
Затем, когда-нибудь позже, достать зашифрованный текст из файла и расшифровать его. Но SecretKey к моменту расшифровки у меня ведь уже не будет