Генерация пары ключей RSA для Android - стоит ли использовать стандартную Java / Bouncy Castle / Spongy Castle / JSch / Other? - PullRequest
33 голосов
/ 01 апреля 2012

Я искал около недели +, чтобы реализовать метод, который я имею в виду.Я сталкивался (и читал) много статей по всем этим различным методам, но я все еще растерялся, поэтому я надеялся, что кто-то может распространить свои знания по этим темам, чтобы мне было легче приступить к созданию своего востребованного метода иреализуя его в Android.

Мой "востребованный" метод:

  1. Должен генерировать открытый и закрытый ключи RSA
  2. Открытый должен иметь PKCSЗаполнение # 1
  3. Должно быть RSA 2048
  4. Возвращать открытый ключ в байтовом массиве

Очевидно, вы можете сделать это четырьмя способами:

  1. Стандартная Java
  2. Надувной замок
  3. Губчатый замок (для Android?)
  4. JSch

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

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

1.Стандартная Java (не уверен, если PKCS # 1):

public byte[] returnPublicKeyInBytes() throws NoSuchAlgorithmException {
    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(2048);
    KeyPair keyPair = kpg.genKeyPair();
    byte[] pri = keyPair.getPrivate().getEncoded();
    byte[] pub = keyPair.getPublic().getEncoded();
    return pub;
}

2.Надувной замок (еще не работает = / Идеи?):

public byte[] returnPublicKeyInBytes() throws NoSuchAlgorithmException {
    RSAKeyPairGenerator r = new RSAKeyPairGenerator();
    r.init(new KeyGenerationParameters(new SecureRandom(),4096));
    AsymmetricCipherKeyPair keys = r.generateKeyPair();
    CipherParameters pri = keys.getPrivate();
    CipherParameters pub = keys.getPublic();
    byte[] pubbyte = pub.toString().getBytes();
    return pubbyte; //NOT WORKING
}

3.SpongyCastle (Разве он не запущен / То же, что и Надувной замок?):

4.JSch (очень неработоспособен / работа в процессе)

public byte[] returnPublicKeyInBytes(JSch jSch) {
    try { 
        KeyPair keyPair = KeyPair.genKeyPair(jSch, KeyPair.RSA);
        ByteArrayOutputStream bs = new ByteArrayOutputStream(); 
        keyPair.writePrivateKey(bs); 
        jSch.addIdentity("Generated", bs.toByteArray(), keyPair.getPublicKeyBlob(), null);
        return keyPair.getPublicKeyBlob(); 
    } catch (JSchException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
    }
    return null;
}

Я бы хотел, чтобы это стало настоящим ресурсом для тех, у кого есть проблемы с генерацией RSA-ключа в Android (например, я и многие другие)


Я чувствую, что Bouncy Castle имеет очень мало информации о его API, что делает чрезвычайно трудным для начинающего (такого как я)понимать это.Из моего исследования люди используют Bouncy Castle в Java вместо встроенного поставщика безопасности, потому что Bouncy Castle намного надежнее .Использование Bouncy Castle в Android нежелательно , поскольку он «поставляется с урезанной версией Bouncy Castle», которая может быть подвержена ошибкам.Spongy Castle - это просто переупаковка Bouncy Castle.

С этой целью я задам свой последний вопрос о том, какой метод следует использовать для Android?

Update

Надеюсь, кто-нибудь ответит позже.Что касается того, что я сделал, чтобы решить мою проблему, так это просто использовать NDK.

Ответы [ 2 ]

45 голосов
/ 01 апреля 2012

Это сложно, но я постараюсь объяснить как можно лучше. Я думаю, что я начну с Java. Мое обсуждение ориентировано на Java 6, я не уверен, что изменилось в Java 7.

Встроенная в Java криптография доступна через Java Cryptography Extension (JCE). Это расширение состоит из двух частей: API приложения и API поставщика услуг. API приложения - это та часть, с которой вы взаимодействуете. Вы используете фабричные методы getInstance() различных классов шифрования. Аспект поставщика услуг более запутан для среднего программиста. Их не волнует, как реализована криптография, они просто хотят что-то, что работает. Но под капотом есть классы провайдеров шифрования, которые выполняют реальную работу. Если вы посмотрите на аргументы getInstance(), вы увидите, что можете указать поставщика, если хотите. Зачем тебе это? Возможно, вы заплатили $$$ за оптимизированную коммерческую реализацию RSA, поэтому вы хотите использовать ее. Возможно, у одного провайдера есть сертификат FIPS или другой сертификат, который вам нужен для вашего приложения. Тогда вы бы указали этого провайдера. Sun / Oracle поставляет свою среду Java вместе с несколькими поставщиками , которые вместе составляют набор поставщиков по умолчанию для их среды Java. Не смотрите на них слишком внимательно, потому что они частично совпадают и, таким образом, сбивают с толку из-за исторических артефактов. По сути, при использовании Oracle Java вы запрашиваете некоторую криптографию, например от KeyPairGenerator до KeyPairGenerator.getInstance("RSA");, вы получаете соответствующий экземпляр класса от одного из этих провайдеров.

Далее, давайте посмотрим на бодрый замок. Bouncycastle библиотека состоит из двух частей. Одна из них - это их уникальная крипто библиотека, API которой вы экспериментировали с # 2 выше. Вторая часть - это большой код, позволяющий использовать эту библиотеку в качестве провайдера шифрования для JCE. Это означает, что у вас, как у программиста, есть выбор, как использовать криптографическую библиотеку bouncycastle. Вы можете использовать их API напрямую, как в # 2 выше. Или вы можете использовать API JCE, но явно указать реализацию bouncycastle чем-то вроде KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");.

Если вы предпочитаете использовать уникальный API-интерфейс bouncycastle напрямую (они называют его «легковесным API-интерфейсом»), то вам не нужен весь связующий код, используемый для его работы в качестве JCE-провайдера. Для этого Bouncycastle действительно обеспечивает загрузку только легких классов API.

И теперь, наконец, мы рассмотрим реализацию Android. Google не лицензировал исходный код Java для Oracle, поэтому у них не было ни одного поставщика Oracle JCE. Они должны были предоставить своих собственных поставщиков. Поскольку у bouncycastle был весь необходимый код, и он был с открытым исходным кодом и свободно лицензирован, Google / Android решил использовать bouncycastle в качестве основы для своего поставщика JCE по умолчанию. Но Android не приложил усилий, чтобы сделать доступным уникальный легкий API для программистов Android. Они ожидают, что вы будете использовать эти классы исключительно через JCE. Они изменили код Bouncycastle, чтобы настроить его для Android. Тот факт, что вы можете найти и, возможно, использовать некоторый облегченного API непосредственно на Android, является просто побочным эффектом того факта, что он находится под капотом. И не все там. Некоторые описывают эту ситуацию как «бодрящий замок на Android поврежден».

Чтобы предоставить полнофункциональную версию библиотеки bouncycastle на Android, некоторые разработчики создали нечто вроде Spongycastle library . Это не что иное, как библиотека bouncycastle, модифицированная так, чтобы она могла работать на Android. Главное изменение состояло в том, чтобы изменить имена пакетов с org.bouncycastle.* на org.spongycastle.*, чтобы предотвратить конфликты пространства имен.

Так что вы должны использовать?Это зависит от того, что вы хотите сделать, каковы ваши потребности в мобильности, каковы ваши стилевые предпочтения и какой у вас уровень крипто-навыков.В общем, когда вы используете эти библиотеки, вы используете crypto на довольно низком уровне.Вы концентрируетесь на том, как это сделать (использовать RSA для передачи ключей, использовать AES для шифрования сообщений, использовать HMAC-SHA256 для целостности сообщений и т. Д.), А не на том, что делать (я хочу отправить зашифрованное сообщение получателю по электронной почтемеханизм)Очевидно, что если вы можете, вы должны придерживаться библиотек более высокого уровня, которые напрямую решают вашу проблему.Эти библиотеки уже понимают, что такое PKCS # 1 и как использовать его как часть более крупных и полных протоколов.

1 голос
/ 01 апреля 2012

Сегодня я помогал кому-то сегодня с надувным замком.Его код работает, поэтому проверьте его

Пары ключей RSA, генерируемые с использованием надувного замка.Создание кода, запускаемого из Java-программы

...