Да, приемник использует только модуль и показатель степени;нет других компонентов, которые необходимы математически для проверки подписи для RSA.
Математические операции выполняются с использованием больших чисел (обычно BigInteger
значения, когда RSA реализуется в программном обеспечении).Для выполнения любого вида расчета реализация должна восстановить эти числа.То, как эти числа передаются, не имеет значения для алгоритма.
Обычно открытые ключи RSA кодируются с использованием чего-то на основе PKCS # 1, который определяет формат открытого ключа с использованием ASN.1 (который определяет структуру) иBER / DER (который определяет кодировку этой структуры).Конечно, разные протоколы могут использовать разные кодировки открытых ключей.Например, PGP использует совершенно другой «формат пакета» для кодирования ключей.
Java, однако, возвращает структуру SubjectPublicKeyInfo, которая определена в спецификациях X.509 (сертификат и CRL);кроме того, модуль и экспонента также содержит идентификатор алгоритма, который показывает, что он является открытым ключом RSA.Таким образом, эта структура также может быть использована для распределения других видов значений ключей.Его можно получить, вызвав getEncoded()
в экземпляре RSAPublicKey
- при условии, что этот экземпляр совместим с предоставленным Oracle - они обычно таковыми и являются.Разумеется, реализации Android должны быть совместимы с этой структурой.Обратите внимание, что структура SubjectPublicKeyInfo содержит структуру открытого ключа PKCS # 1 , внутри нее .
Для обратного обращения вам нужно KeyFactory.getInstance("RSA")
и получить ключ, используя X509EncodedKeySpec
, инициализированный с заданныммассив байтов.
Если вам нужны текстовые строки вместо двоичных, то вы можете преобразовать байты, возвращенные getEncoded()
, в основание 64 и шестнадцатеричные числа.Разумеется, в этом случае вам необходимо изменить кодирование (т. Е. Декодировать) результат до того, как вы сможете декодировать сами байты.
Также можно кодировать модуль и открытый показатель степени самостоятельно.Вы можете получить их, используя RSAPublicKey.getModulus()
и RSAPublicKey.getPublicExponent()
.Чтобы вернуть их обратно в RSAPublicKey
, вы можете использовать KeyFactory.getInstance("RSA")
и RSAPublicKeySpec
.Таким образом, вы можете, например, просто создать строку "(<modulus>, <exp>)"
и использовать ее для распространения ключа.Как правило, вы хотели бы придерживаться предварительно определенных стандартов.
В этом ответе не рассматривается тот факт, что для проверки с открытым ключом сначала необходимо установить доверие в открытом доступе.ключ.Если вы не можете доверять открытому ключу, вы не знаете, кто создал открытый ключ.В этом случае вы также не можете доверять результату вашей операции проверки;подпись, возможно, была создана с парой ключей противника.Однако углубляться в инфраструктуры открытого ключа (PKI / PKIX) для этого ответа слишком сложно.
Аналогично: SHA-1 больше не считается безопасным, особенно для генерации / проверки подписи.Вы хотели бы использовать по крайней мере SHA256withRSA
или - немного более продвинутую и несколько более безопасную - схему RSA, которая использует PSS.2048 бит слишком мал для комфорта;рекомендуется использовать 4096-битный ключ, если ваша схема это позволяет.