Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Шифрование


Автор: Swatch 30.7.2007, 13:25
Добрый день.

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

Автор: LSD 30.7.2007, 14:14
В данном случае все просто:
  • создаешь свой класс где записываешь дату действия ключа, на кого он выдан и т.п.
  • реализуешь методы которые будут записывать и считывать эту структуру в бинарный поток (можно обойтись просто сериализацией)
  • далее http://java.sun.com/docs/books/tutorial/security/apisign/step3.html полученные данные
  • формируешь файл ключа: первая половина данные ключа, вторая его подпись
  • зашиваешь в свою программу публичный ключ использовавшийся для подписи
  • при запуске читаешь данные ключа и проверяешь подпись

Автор: Swatch 30.7.2007, 14:45
Это я понимаю... Спасибо. Но я слабо представляю, как это сделать.  smile 
Мне сказали, создать класс, в котором будет открытый ключ. Потом этим открытым ключом шифровать дату и срок действия. полученный зашифрованный файл отдавать юзеру. Приветдите, пожалуйста, пример класса, в котором будет открытый ключ, реализующий без разницы, какой алгоритм. и, если можно, пример, как потом это откр. ключ использовать. 

Автор: LSD 30.7.2007, 15:50
В той ссылке, что я дал, все есть. И как сгенерировать пару ключей, и как их сохранить. Ты можешь или сохранить файл с ключем в jar с твоей программой, или сгенерировать класс, где жестко закодировать ключ.

Автор: Swatch 31.7.2007, 07:01
Я, конечно, понимаю, что я туплю, но по ссылке, которую Вы дали, я вообще ничего понять не могу.  smile Если не сложно, скажите, плиз, по шагам, куда смотреть, чтобы сделать (а лучше, как сделать):

1. зашифровать текущую дату и срок действия. (это будет лиц. ключ, который после ввода юзером, будет храниться в базе)

2. при открытии программы расшифровывать данные (как считать из базы, я знаю, пусть это будет какая-то строка).

Я просто в упор не понимаю, где передаются данные для шифрования, чем они шифрутся и куда сохраняются... и как их потом расшифровать?!  smile Мне нужно,чтобы сейчас моя строка, пусть такая "31.07.2007 365" зашифровалась куда-нибудь в файл... и чтобы потом я смогла ее из зашифрованного обратно в такой "31.07.2007 365" вид привести. Спасибо.

Автор: Swatch 31.7.2007, 07:59
Дело в том, что мне нужен только открытый ключ... просто им зашифровать и отдать юзеру... что-то такое надо:


Код

       Cipher c1 = Cipher.getInstance("DES");
       c1.init(c1.ENCRYPT_MODE,???); //
       byte [] raw = c1.doFinal(???);


какие параметры передаются вместо знаков ???? подскажите, пожалуйста. я так понимаю, что вот здесь byte [] raw будут зашифрованные данные... как их потом в String можно будет перевести, не подскадите?

Автор: Alexandr87 31.7.2007, 08:21
Код

    public static void main(String[] args)
    throws Exception {
        
        KeyGenerator kg = KeyGenerator.getInstance("DES");
        Key desKey = kg.generateKey();
        
        Cipher ciph = Cipher.getInstance("DES");
        ciph.init(Cipher.ENCRYPT_MODE, desKey);

        byte key[] = desKey.getEncoded();
        byte enc[] = ciph.doFinal("18.03.1987".getBytes());
        
        System.out.println("Key:");
        System.out.println(bArrayToHex(key));
        
        System.out.println("Encrypted data:");
        System.out.println(bArrayToHex(enc));
        
    }
    
    public static String bArrayToHex(byte array[]) {
        StringBuffer sb = new StringBuffer(array.length*2);
        
        for (int i = 0; i < array.length; i++) {
            if (array[i] <0) {
                sb.append(Integer.toString(array[i]+256, 16));
            } else {
                if (array[i]<16) {
                    sb.append("0");
                }
                
                sb.append(Integer.toString(array[i], 16));
            }
        }
        
        return sb.toString();
    }


Для вывода байтовых массивов у меня есть небольшой утил пак, который конвертит их из/в строку в хексе.

На самом деле, вариант, который предложил LSD более правильный.

Автор: Swatch 31.7.2007, 08:26
Может он и правильный, я не спорю. Просто моему ПМ нужно именно так. Большое спасибо за помощь LSD и Alexandr87!!!  

Автор: Swatch 31.7.2007, 08:44
Еще один маааленький вопросик... я так поняла, byte key[] - это и есть мой откр. ключ, а byte enc[] - это зашифрованные мои данные. А как теперь использовать именно этот ключ, чтобы данные расшифровать?

Автор: Alexandr87 31.7.2007, 09:15


Код

        // decrypt
        DESKeySpec dkspc = new DESKeySpec(key);
        SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
        Key desKey2 = skf.generateSecret(dkspc);
        
        Cipher ciph2 = Cipher.getInstance("DES");
        ciph2.init(Cipher.DECRYPT_MODE, desKey2);
        byte mess[] = ciph2.doFinal(enc);
        
        System.out.println("Mes:");
        System.out.println(new String(mess));
        


Цитата(Swatch @  31.7.2007,  11:44 Найти цитируемый пост)
byte key[] - это и есть мой откр. ключ,

понятие открытый ключ существует только в контексте асиммитричного шифрования, и обозначает такую ключевую информацию которую можно открыто распрострнять. В данном случае - это симметричный алгоритм шифрование - и подобные ключи называются либо секретными, либо сессионными. Я это все к чему, может быть 
Цитата(Swatch @  31.7.2007,  11:26 Найти цитируемый пост)
. Просто моему ПМ нужно именно так

нужно именно не так?

Автор: Swatch 31.7.2007, 09:24
Нет, ему именно так нужно... просто, видимо, у него тоже с понятиями не очень хорошо, как и у меня... Он сначала сказал, открытый ключ... я поискала... везде открытый идет вместе с закрытым. Донесла эту инфу до него. Он поискал вместе со мной, т.к. я тож до конца не понимала, что и как он хочет. Нашел эссе по курсу "Обзор Java Crypto API". там был пункт симметричные и несимметричные шифры. только тогда я поняла, что он хочет. я это уже находила... и это именно то, что Вы написали. просто понятия неправильные.

Автор: Swatch 31.7.2007, 09:58
Написала вот так. Мне нужно было 2 отдельных метода: 

Код

    public String secretkey;
    public String licensekey;

public frmMain() {
        initComponents(); 
        Encrypt(LicenseKey.licens_cod);
        Decrypt(secretkey,licensekey);
} 
public void Encrypt(String args){
        KeyGenerator kg;
        try {
            kg = KeyGenerator.getInstance("DES");
            SecretKey desKey = kg.generateKey();
            Cipher c1 = Cipher.getInstance("DES");
            c1.init(Cipher.ENCRYPT_MODE,desKey); 
    
            byte key[] = desKey.getEncoded();
            byte enc[] = c1.doFinal(args.getBytes());
            
            secretkey = bArrayToHex(key);
            licensekey = bArrayToHex(enc);
            
         } catch (Exception e){
           e.printStackTrace();
         }
}
     
     public void Decrypt(String sec_key, String lic_key){
        try {
            DESKeySpec dkspc = new DESKeySpec(sec_key.getBytes());
            SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
            Key desKey2 = skf.generateSecret(dkspc);
            
            Cipher c2 = Cipher.getInstance("DES");
            c2.init(Cipher.DECRYPT_MODE, desKey2);
            byte mess[] = c2.doFinal(lic_key.getBytes());
            
            jTextField1.setText(new String (mess));
            
         } catch (Exception e){
           e.printStackTrace();
         }
}


В args передается строка с датой ну и т.д. Подскажите, плиз, что не так? падает на строке byte mess[] = c2.doFinal(lic_key.getBytes()); и все. Пишет javax.crypto.BadPaddingException: Given final block not properly padded.

Автор: Alexandr87 31.7.2007, 10:07
Swatch, проблема в том, что вы передаете во все эти методы не байтовые массивы, а хексовое представление их (bArrayToHex). Нужно перед вызвовом процедуры расшифровки конвертнуть их назад в байтовые массивы. Предугадывая следующий пост, выложим сразу:
Код

    public static byte[] bArrayFromHex(String arrayInHex)
    throws Exception {
        
        if (arrayInHex.length()%2 != 0) {
            throw new Exception("BadFormat");
        }
        
        ByteArrayOutputStream baos = new ByteArrayOutputStream(
                arrayInHex.length()/2);
        
        for (int i = 0; i < arrayInHex.length(); i+=2) {
            baos.write((byte)Integer.parseInt(arrayInHex.substring(i, i+2), 16));
        }
        
        return baos.toByteArray();
    }

Автор: Swatch 31.7.2007, 10:41
Разобралась в чем дело. теперь встал вопрос о написании метода подобного Вашему bArrayToHex. Только из строки теперь надо получить массив байт... Можете, пожалуйста, объяснить, что там у Вас делается...

Добавлено через 6 минут и 50 секунд
Да уж, написала пост, не обновив страничку... Спасибо огромное, все делается!!! Ребята, Вы просто супер!!! Спасибо-спасибо!!!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)