Экспорт открытого ключа RSA в строку PEM с помощью java

Итак, я использую Spongy Castle (Android) для создания закодированной строки PEM для открытого ключа RSA, который будет загружен на сервер. Это то, что я сейчас делаю:

    PublicKey publicKey = keyPair.getPublic();
    StringWriter writer = new StringWriter();
    PemWriter pemWriter = new PemWriter(writer);
    pemWriter.writeObject(new PemObject("RSA PUBLIC KEY", publicKey.getEncoded()));
    pemWriter.flush();
    pemWriter.close();
    return writer.toString();

Теперь, как вы, вероятно, можете сказать, я не уверен, как построить PemObject или есть ли более простой способ сделать это.

При использовании Bouncy Case я делал это так

    StringWriter writer = new StringWriter();
    PEMWriter pemWriter = new PEMWriter(writer);
    pemWriter.writeObject(keyPair.getPublic());
    pemWriter.flush();
    pemWriter.close();
    return writer.toString();

Но по какой-то причине класса PEMWriter в Spongy Castle нет.


person fernandohur    schedule 05.08.2014    source источник
comment
Каков формат publicKey.getEncoded после того, как мы закодировали его с помощью Base64? Это пэм?   -  person Charlesjean    schedule 23.12.2019


Ответы (2)


Итак, это, вероятно, не самый умный способ (или, может быть, это так?) Сделать это, но после проверки исходных кодов для PEMWriter этот класс в основном делает это под капотом:

  1. при вызове writeObject он создает экземпляр MiscPEMGenerator
  2. MiscPEMGenerator затем создает PemObject, проверяя тип аргумента конструктора, ниже приведен отрывок из исходного кода MiscPEMGenerator:

    private PemObject createPemObject(Object o){
      ...
      else if (o instanceof PublicKey)
      {
          type = "PUBLIC KEY";
    
          encoding = ((PublicKey)o).getEncoded();
      }
      ...
      return new PemObject(type, encoding);
    }
    

Итак, как видно из кода MiscPEMGenerator, единственное, что мне пришлось изменить, это параметр типа с «RSA PUBLIC KEY» на просто «PUBLIC KEY». Вот окончательный код.

PublicKey publicKey = keyPair.getPublic();
StringWriter writer = new StringWriter();
PemWriter pemWriter = new PemWriter(writer);
pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKey.getEncoded()));
pemWriter.flush();
pemWriter.close();
return writer.toString();
person fernandohur    schedule 05.08.2014

Причина, по которой вы можете столкнуться с проблемами, заключается в том, что Android использует Bouncy Castle для внутреннего использования в качестве поставщика JCA. Но включенная версия зависит от версии Android.

Вас может заинтересовать проект Spongy Castle, который "просто" переупаковывает Bouncy Castle в другой пакет, поэтому что вы можете включать свои собственные библиотеки в ваше Android-приложение.

Используя последнюю версию (1.51.0.0) Spongy Castle, следующее работает так, как предполагалось (на моей рабочей станции нет под рукой устройства для тестирования на устройстве):

import java.security.PublicKey;
import org.spongycastle.openssl.jcajce.JcaPEMWriter;

class PEMConverter {

    public static String toPEM(PublicKey pubKey) {
        StringWriter sw = new StringWriter();
        JcaPEMWriter pemWriter = new JcaPEMWriter(sw);
        pemWriter.writeObject(pubKey);
        pemWriter.close();
        return sw.toString();
    }
}
person Martin C.    schedule 09.08.2014