Показаны сообщения с ярлыком шифрование. Показать все сообщения
Показаны сообщения с ярлыком шифрование. Показать все сообщения

пятница, 4 февраля 2011 г.

Несложный класс для шифрования и дешифрования строки на Java c сохраняемым в программе ключом

С помощью нижеприведенного класса можно легко зашифровать некоторую строку (например пароль) с использование алгоритма DES, и затем при желании расшифровать её. При этом секретный ключ сохранен в теле класса, так что строку можно будет расшифровать даже после перезапуска программы.

// Файл SecuritySettings.java

package security;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

/**
 *
 * @author Cloud
 */


public final class SecuritySettings {

    private final static class MySecretKey implements SecretKey {

        private byte[] key = new byte[]{1, 2, 3, 4, 5, 6, 7, 8}; // ключ
      // не должен иметь длину более 8 байт, для безопасного шифрования его
      // необходимо изменить 

        public String getAlgorithm() {
            return "DES";
        }

        public String getFormat() {
            return "RAW";
        }

        public byte[] getEncoded() {
            return key;
        }
    }

    private static SecretKey key;

    private static Cipher ecipher;
    private static Cipher dcipher;

    static {
        try {
            key = new MySecretKey();
            ecipher = Cipher.getInstance("DES");
            dcipher = Cipher.getInstance("DES");
            ecipher.init(Cipher.ENCRYPT_MODE, key);
            dcipher.init(Cipher.DECRYPT_MODE, key);
        } catch (InvalidKeyException ex) {
            Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchAlgorithmException ex) {
            Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchPaddingException ex) {
            Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


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

    /**
     * Функция расшифрования
     * @param str зашифрованная строка в формате Base64
     * @return расшифрованная строка
     */
    public static String decrypt(String str)  {
        try {
            byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
            byte[] utf8 = dcipher.doFinal(dec);
            return new String(utf8, "UTF8");
        } catch (IllegalBlockSizeException ex) {
            Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
        } catch (BadPaddingException ex) {
            Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(SecuritySettings.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
}


UPD 06.02.13
Выкладываю обновленную версию класса. В новой версии используется сторонняя билиотека Apache Codec http://commons.apache.org/codec/, также методы класса сделаны нестатическими, благодаря чему стало возможным с данным классом создавать несколько шифрователей с разными ключами или алгоритмами в одном приложении и динамически менять ключ шифрования. Минимальная версия jdk - 1.7, однако после внесения небольших изменений может использоваться и на более ранних версиях java.

// Файл StringCrypter.java
package rva.common.util;

import java.io.IOException;
import org.apache.commons.codec.binary.Base64;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;

/**
 * Класс для шифрования и дешифрования строк
 * Использует библиотеку Apache Codec http://commons.apache.org/codec/
 * @author Рудницкий Валентин
 */
public class StringCrypter {

    /**
     * Упрощенный конструктор. Создает StringCrypter с ключом DESSecretKey со значением по умолчанию (не рекомендуется)
     */
    public StringCrypter() {
        this(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});
    }
    
    /**
     * Упрощенный конструктор. Создает StringCrypter с ключом 
     * DESSecretKey (алгоритм шифрования DES) со значением key. 
     * Ключ key должен иметь длину 8 байт
     */
    public StringCrypter(byte[] key) {
        try {
            updateSecretKey(new DESSecretKey(key));
        } catch (InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException ex) {
            throw new IllegalArgumentException(ex.getMessage());
        }
    }

    public StringCrypter(SecretKey key) throws NoSuchPaddingException,
            NoSuchAlgorithmException,
            InvalidKeyException {
        updateSecretKey(key);
    }

    private void updateSecretKey(SecretKey key) throws NoSuchPaddingException,
            NoSuchAlgorithmException,
            InvalidKeyException {
        ecipher = Cipher.getInstance(key.getAlgorithm());
        dcipher = Cipher.getInstance(key.getAlgorithm());
        ecipher.init(Cipher.ENCRYPT_MODE, key);
        dcipher.init(Cipher.DECRYPT_MODE, key);
    }

    public static class DESSecretKey implements SecretKey {

        private final byte[] key;

        /**
         * ключ должен иметь длину 8 байт
         */
        public DESSecretKey(byte[] key) {
            this.key = key;
        }

        @Override
        public String getAlgorithm() {
            return "DES";
        }

        @Override
        public String getFormat() {
            return "RAW";
        }

        @Override
        public byte[] getEncoded() {
            return key;
        }
    }

    private Cipher ecipher;
    private Cipher dcipher;

    /**
     * Функция шифрования
     *
     * @param str строка открытого текста
     * @return зашифрованная строка в формате Base64
     */
    public String encrypt(String str) {
        try {
            byte[] utf8 = str.getBytes("UTF8");
            byte[] enc = ecipher.doFinal(utf8);
            return Base64.encodeBase64String(enc);
        } catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException ex) {
            Logger.getLogger(StringCrypter.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    /**
     * Функция дешифрования
     *
     * @param str зашифрованная строка в формате Base64
     * @return расшифрованная строка
     */
    public String decrypt(String str) {
        try {
            byte[] dec = Base64.decodeBase64(str);
            byte[] utf8 = dcipher.doFinal(dec);
            return new String(utf8, "UTF8");
        } catch (IllegalBlockSizeException | BadPaddingException | IOException ex) {
            Logger.getLogger(StringCrypter.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
}


Пример использования нового класса

// создаем экземпляр класса StringCrypter с ключем шифрования
  StringCrypter crypter=new StringCrypter(new byte[]{1,4,5,6,8,9,7,8});
  String testStr = "forCryptString";
// шифрование
  String encBase64Str = crypter.encrypt(testStr);

// дешифрование
  String decryptedStr = crypter.decrypt(encBase64Str);
        

Ярлыки

java (31) оптимизация (7) CPanel (5) svn (5) windows xp (5) ошибка (5) свой сервер (5) файлы и папки (5) gui (4) регулярные выражения (4) jacoco (3) redmine (3) windows (3) автоматизация (3) защита данных (3) резервное копирование (3) сервер (3) JavaScript (2) Oracle SQL (2) adsl модем (2) apache maven (2) apache tomcat (2) coverage (2) dropbox (2) excel (2) firewall (2) netbeans (2) office 2007 (2) samsung (2) system tray (системный трей) (2) xerox (2) вирусы (2) принтер (2) сериализация (2) удаленный рабочий стол (2) HTML (1) JFileChooser (1) MySQL (1) Nokia (1) Ovi (1) P660R-T1 (1) WakeOnLan (1) blogger.com (1) ctfmon.exe (1) email (1) flash память (1) ftp (1) integration testing (1) ip (1) jQuery (1) jvisualWm (1) log4j (1) look and feel (1) myBatis (1) php (1) serialVersionUID (1) skype (1) smtp (1) ssh (1) swing (1) torrents (1) unit-testing (1) unix (1) vpn (1) windows 7 (1) xStarter (1) zip (1) безопасность (1) вход в систему (1) дизайн (1) документация (1) заправка (1) интернет (1) логирование (1) мышь (1) патч (1) перенос (1) печать (1) плагины (1) почтовые сообщения (1) программирование (1) процессы (1) прошивка (1) сеть (1) сеть. ошибка (1) скрытые файлы (1) списки (1) фильтрация (1) фокус (1) часовые пояса (1) шифрование (1) экран (1)