Модераторы: LSD, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> алгоритм RSA не всегда работает 
:(
    Опции темы
4epT
Дата 2.11.2010, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Добрый день! Скачал в интернете класс который позволяет шифровать и расшифровывать методом RSA. Вот исходный код:

Код

import java.math.BigInteger;
import java.security.SecureRandom;


public class RSA {
   private final static BigInteger one      = new BigInteger("1");
   private final static SecureRandom random = new SecureRandom();

   private BigInteger privateKey;
   private BigInteger publicKey;
   private BigInteger modulus;

   // generate an N-bit (roughly) public and private key
   RSA(int N) {
      BigInteger p = BigInteger.probablePrime(N/2, random);
      BigInteger q = BigInteger.probablePrime(N/2, random);
      BigInteger phi = (p.subtract(one)).multiply(q.subtract(one));

      modulus    = p.multiply(q);
      publicKey  = new BigInteger("65537");     // common value in practice = 2^16 + 1
      privateKey = publicKey.modInverse(phi);
   }


   BigInteger encrypt(BigInteger message) {
      return message.modPow(privateKey, modulus);
   }

   BigInteger decrypt(BigInteger encrypted) {
      return encrypted.modPow(publicKey, modulus);
   }

    @Override
   public String toString() {
      String s = "";
      s += "public  = " + publicKey  + "\n";
      s += "private = " + privateKey + "\n";
      s += "modulus = " + modulus;
      return s;
   }
}


дело в том что если шифровать простой текст, то все хорошо работает к примеру вот такой аод работает:

Код

RSA key = new RSA(2048);

        // create message by converting string to integer
        String s = "Hello";
        
        byte[] bytes = s.getBytes();
        BigInteger message = new BigInteger(bytes);

        BigInteger encrypt = key.encrypt(message);
        BigInteger decrypt = key.decrypt(encrypt);
        System.out.println("message   = " + message);
        System.out.println("encrpyted = " + encrypt);
        System.out.println("decrypted = " + decrypt);


но если шифровтаь хеш этого текста то получаеться черт знате что. Вот код который не работает:

Код

RSA key = new RSA(2048);

        // create message by converting string to integer
        String s = "Hello";

        MessageDigest md = MessageDigest.getInstance("MD5");

        byte[] bytes = s.getBytes();

        md.update(bytes);
        byte[] bytesHash = md.digest();
        
        BigInteger message = new BigInteger(bytesHash);

        BigInteger encrypt = key.encrypt(message);
        BigInteger decrypt = key.decrypt(encrypt);
        System.out.println("message   = " + message);
        System.out.println("encrpyted = " + encrypt);
        System.out.println("decrypted = " + decrypt);


в чем может быть проблема? Или подскажите где можно взять реализацию RSA на Java ... RSA нужен именно для ЭЦП (Электронно цифровой подписи)
PM MAIL   Вверх
Skipy
Дата 2.11.2010, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 487
Регистрация: 24.8.2006
Где: Москва, Россия

Репутация: 6
Всего: 16



Цитата(4epT @ 2.11.2010,  16:37)
Или подскажите где можно взять реализацию RSA на Java ... 

RSA на Java можно взять в самой Java.  http://download.oracle.com/javase/6/docs/t...rity/index.html

Неожиданно, правда?


--------------------
С уважением,
Евгений aka Skipy
www.skipy.ru
PM MAIL WWW ICQ   Вверх
4epT
Дата 2.11.2010, 19:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(Skipy @ 2.11.2010,  18:57)
Цитата(4epT @ 2.11.2010,  16:37)
Или подскажите где можно взять реализацию RSA на Java ... 

RSA на Java можно взять в самой Java.  http://download.oracle.com/javase/6/docs/t...rity/index.html

Неожиданно, правда?

смешно конечно но скачать исходник у меня не получается
PM MAIL   Вверх
jk1
Дата 2.11.2010, 20:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Цитата

смешно конечно но скачать исходник у меня не получается 


Ничего не надо скачивать, этот исходник в составе JDK есть.

1.Генерируете ключ:

Код

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
Key publicKey = kp.getPublic();
Key privateKey = kp.getPrivate();


2. Шифруете

Код

public byte[] rsaEncrypt(byte[] data) {
  Cipher cipher = Cipher.getInstance("RSA");
  cipher.init(Cipher.ENCRYPT_MODE, pubKey);
  byte[] cipherData = cipher.doFinal(src);
  return cipherData;
}



--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
4epT
Дата 2.11.2010, 23:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



jk1, спасибо большое за помощь) помогло!
Но теперь столкнулся с другой проблемой ... мне нужно этот зашиврованый текст дописать в конец сообщения а потом извлечь его расшифровать. НА тапе конвертирования из массива байтов в строку и из строки обратно в массив байтов изменяются значения =(( как это правильно сделать? я делаю вот так:

Код

          byte[] sign = encrypt(hash);
          String signStr = new String(sign);


и обратно:

Код

         byte[] sign = signStr.getBytes();

PM MAIL   Вверх
jk1
Дата 3.11.2010, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Цитата

String signStr = new String(sign);


Вот так никогда поступать не стоит. Стока как контейнер массива байтов не работает, потому что воспринимает байты с учетом кодировки.
В вашем случае байты надо переводить в стоковый вид посредством Base64 кодирования:

Код

String digest = (new BASE64Encoder()).encode(bytes); 


Тут правда следует оговориться, что эта реализация B64 будет доступна только на JDK от Oracle, поэтому правильнее будет включить в состав исходников реализацию B64, например вот эту


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
dorogoyIV
Дата 3.11.2010, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

Репутация: 3
Всего: 46



sorry
its offtopic  smile 

jk1, молодец, помнится только ссылками кормил, а теперь коды пишешь  smile 
приятно даже смотреть на это  smile 
плюс тебе
PM MAIL   Вверх
jk1
Дата 3.11.2010, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Offtopic:
Цитата

молодец, помнится только ссылками кормил, а теперь коды пишешь

Времени свободного стало побольше, хватает и на примеры.
Цитата

плюс тебе 

Спасибо


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
4epT
Дата 3.11.2010, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



jk1, спасибо за класс Base64. Он помог решить эту проблему))) но все равно что то у меня не получаеться =(

при декодировании в пределах одной функции все хорошо. Хешь (MD5) сообщения совпадает с расшифрованным. Вот кусочек кода:

Код

            byte[] hash = md.digest();

            byte[] sign = encrypt(hash);

            String signStr = Base64.encodeToString(sign, false);
            message.setLengthSign(signStr.length());
            message.addSignToMessage(signStr);

            byte[] decrypt;
            decrypt = decrypt(Base64.decode(message.getSign()));


и делаю точно такой же вызов декодирования, но уже из другой функции:

Код

            byte[] decrypt;
            decrypt = decrypt(Base64.decode(message.getSign()));


и массивы байт отличаються ...

методы вызываю вот так вот:

Код

        Message message = new Message("Hello, world!");

        ECP.signMessage(message);

        System.out.println(ECP.verify(message));



кто нибудь может подсказать, где я ошибся?))

Это сообщение отредактировал(а) 4epT - 3.11.2010, 18:01
PM MAIL   Вверх
jk1
Дата 3.11.2010, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Цитата

кто нибудь может подсказать, где я ошибся?))


А вы случайно ключи не перегенерируете для каждого вызова?


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
4epT
Дата 3.11.2010, 23:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(jk1 @ 3.11.2010,  23:11)
Цитата

кто нибудь может подсказать, где я ошибся?))


А вы случайно ключи не перегенерируете для каждого вызова?

Ключи статические ... инициализируються в статической области:

Код

{
              //Генерация ключей ...
}


но для уверенности сейчас выведу ключи в обеих методах.
PM MAIL   Вверх
4epT
Дата 4.11.2010, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



ключи одинаковые =(
есть еще варианты?)
PM MAIL   Вверх
jk1
Дата 4.11.2010, 09:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Цитата

есть еще варианты?) 

На основании приведенного нет. Вы не могли бы запостить несколько классов целиком, чтобы я мог воспроизвести проблему? Особенно интересуют классы ECP и Message.


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
4epT
Дата 4.11.2010, 10:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 784
Регистрация: 13.8.2007

Репутация: нет
Всего: 3



Цитата(jk1 @ 4.11.2010,  09:24)
Цитата

есть еще варианты?) 

На основании приведенного нет. Вы не могли бы запостить несколько классов целиком, чтобы я мог воспроизвести проблему? Особенно интересуют классы ECP и Message.

да, без проблем.

ECP
Код

package testrsa;

import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
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;

public class ECP
{
    private static Key publicKey = null;
    private static Key privateKey = null;
    private static final int sizeKeys = 1024;

    public ECP()
    {
        

    }

    static
    {
        KeyPairGenerator kpg;
        try
        {
            kpg = KeyPairGenerator.getInstance("RSA");
            kpg.initialize(sizeKeys);
            KeyPair kp = kpg.genKeyPair();
            publicKey = kp.getPublic();
            privateKey = kp.getPrivate();
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.out.println(ex.getMessage());
        }
    }

    public static Message signMessage(Message message)
    {
        try
        {
            if(publicKey == null || privateKey == null)
                return null;

            MessageDigest md = MessageDigest.getInstance("MD5");

            md.update(message.getDataBytes());
            byte[] hash = md.digest();

            System.out.println("encode");
            System.out.println(publicKey.toString());
            System.out.println(privateKey.toString());
            byte[] sign = encrypt(hash);

            String signStr = Base64.encodeToString(sign, false);
            message.setLengthSign(signStr.length());
            message.addSignToMessage(signStr);

            byte[] decrypt;
            decrypt = decrypt(Base64.decode(message.getSign()));

            System.out.println(Arrays.toString(decrypt));

            //message.addSignTest(sign);

            return message;
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.out.println(ex.getMessage());
            return null;
        }
    }

    public static boolean verify(Message message)
    {
        try 
        {
            if(publicKey == null || privateKey == null)
                return false;
            if(!message.isIsSign())
                return false;
            
            MessageDigest md = MessageDigest.getInstance("MD5");

            String data = message.getMessage();

            System.out.println("decode");
            System.out.println(publicKey.toString());
            System.out.println(privateKey.toString());
            byte[] decrypt;
            decrypt = decrypt(Base64.decode(message.getSign()));

            md.update(data.getBytes());

            byte[] hash = md.digest();

            System.out.println("Verify:");
            System.out.println(Arrays.toString(decrypt));
            System.out.println(Arrays.toString(hash));

            return Arrays.equals(decrypt, hash);
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.out.println(ex.getMessage());
            return false;
        }
    }

    private static byte[] encrypt(byte[] data)
    {
        Cipher cipher;
        byte[] cipherData = null;
        try
        {
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            cipherData = cipher.doFinal(data);
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (NoSuchPaddingException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (InvalidKeyException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (IllegalBlockSizeException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (BadPaddingException ex)
        {
            System.err.println(ex.getMessage());
        }
        finally
        {
            return cipherData;
        }

    }


    private static byte[] decrypt(byte[] data)
    {
        Cipher cipher;
        byte[] cipherData = null;
        try
        {
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            cipherData = cipher.doFinal(data);
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (NoSuchPaddingException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (InvalidKeyException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (IllegalBlockSizeException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (BadPaddingException ex)
        {
            System.err.println(ex.getMessage());
        }
        finally
        {
            return cipherData;
        }

    }
    
}



Message
Код

package testrsa;

public class Message
{
    private String message;
    private boolean isSign = false;
    private int lengthSign = 0;
    private byte[] signTest;

    public Message(String message) 
    {
        this.message = message;
    }

    public boolean isIsSign() 
    {
        return isSign;
    }

    public void setIsSign(boolean isSign) 
    {
        this.isSign = isSign;
    }

    public int getLengthSign() 
    {
        return lengthSign;
    }

    public void setLengthSign(int lengthSign) 
    {
        this.lengthSign = lengthSign;
    }

    public String getMessage() 
    {
        return message;
    }

    public void setMessage(String message) 
    {
        this.message = message;
    }

    public byte[] getDataBytes()
    {
        return this.message.getBytes();
    }

    public void addSignToMessage(String sign)
    {
        this.message += sign;
        this.setIsSign(true);
    }

    public String getSign()
    {
        if(this.isSign)
        {
            return this.message.substring(this.message.length() - this.lengthSign);
        }
        else
        {
            return null;
        }
    }

    public String getData()
    {
        if(this.isSign)
        {
            return this.message.substring(0 , this.message.length() - this.lengthSign);
        }
        else
        {
            return null;
        }
    }

    public void addSignTest(byte[] sign)
    {
        this.signTest = sign;
        this.setIsSign(true);
    }

    public byte[] getSignTest()
    {
        return this.signTest;
    }

}


PM MAIL   Вверх
jk1
Дата 4.11.2010, 11:02 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 40
Всего: 75



Проблема в запутанной логике класса Message. Предлагаю такой вариант:
Код

public class Message {
    private String message;
    private String signature;

    public Message(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getSignature() {
        return signature;
    }

    public void setSignature(String signature) {
        this.signature = signature;
    }
}

Код


import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
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;
public class ECP
{
    private static Key publicKey = null;
    private static Key privateKey = null;
    private static final int sizeKeys = 1024;
    public ECP()
    {

    }
    static
    {
        KeyPairGenerator kpg;
        try
        {
            kpg = KeyPairGenerator.getInstance("RSA");
            kpg.initialize(sizeKeys);
            KeyPair kp = kpg.genKeyPair();
            publicKey = kp.getPublic();
            privateKey = kp.getPrivate();
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.out.println(ex.getMessage());
        }
    }
    public static Message signMessage(Message message)
    {
        try
        {
            if(publicKey == null || privateKey == null)
                return null;
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(message.getMessage().getBytes());
            byte[] hash = md.digest();
            System.out.println("encode");
            System.out.println(publicKey.toString());
            System.out.println(privateKey.toString());
            byte[] sign = encrypt(hash);
            String signStr = Base64.encodeToString(sign, false);

            message.setSignature(signStr);
            byte[] decrypt;
            decrypt = decrypt(Base64.decode(message.getSignature()));
            System.out.println(Arrays.toString(decrypt));
            //message.addSignTest(sign);
            return message;
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.out.println(ex.getMessage());
            return null;
        }
    }
    public static boolean verify(Message message)
    {
        try
        {
            if(publicKey == null || privateKey == null)
                return false;
            if(message.getSignature() == null)
                return false;

            MessageDigest md = MessageDigest.getInstance("MD5");
            String data = message.getMessage();
            System.out.println("decode");
            System.out.println(publicKey.toString());
            System.out.println(privateKey.toString());
            byte[] decrypt;
            decrypt = decrypt(Base64.decode(message.getSignature()));
            md.update(data.getBytes());
            byte[] hash = md.digest();
            System.out.println("Verify:");
            System.out.println(Arrays.toString(decrypt));
            System.out.println(Arrays.toString(hash));
            return Arrays.equals(decrypt, hash);
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.out.println(ex.getMessage());
            return false;
        }
    }
    private static byte[] encrypt(byte[] data)
    {
        Cipher cipher;
        byte[] cipherData = null;
        try
        {
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            cipherData = cipher.doFinal(data);
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (NoSuchPaddingException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (InvalidKeyException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (IllegalBlockSizeException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (BadPaddingException ex)
        {
            System.err.println(ex.getMessage());
        }
        finally
        {
            return cipherData;
        }
    }
    private static byte[] decrypt(byte[] data)
    {
        Cipher cipher;
        byte[] cipherData = null;
        try
        {
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            cipherData = cipher.doFinal(data);
        }
        catch (NoSuchAlgorithmException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (NoSuchPaddingException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (InvalidKeyException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (IllegalBlockSizeException ex)
        {
            System.err.println(ex.getMessage());
        }
        catch (BadPaddingException ex)
        {
            System.err.println(ex.getMessage());
        }
        finally
        {
            return cipherData;
        }
    }

}



--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0941 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.