Как получить открытый ключ RSA из объекта закрытого ключа в Java

Как получить связанный объект открытого ключа java.security.PublicKey из объекта закрытого ключа java.security.PrivateKey в криптосистеме RSA.


person Dennis Kriechel    schedule 15.07.2014    source источник


Ответы (2)


Java может создать открытый ключ, используя модуль и показатель степени:

RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, exponent);
kf.generatePublic(keySpec);

Итак, нам нужно извлечь эти значения из закрытого ключа:

KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec priv = kf.getKeySpec(privateKey, RSAPrivateKeySpec.class);

Теперь RSAPrivateKeySpec-Object содержит нужный нам модуль, но показатель степени не тот, который нам нужен для открытого ключа.

Для открытого ключа показатель степени обычно равен 65537: http://en.wikipedia.org/wiki/65537_(number)

Поэтому теперь мы можем создать открытый ключ:

KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPrivateKeySpec priv = kf.getKeySpec(privateKey, RSAPrivateKeySpec.class);

RSAPublicKeySpec keySpec = new RSAPublicKeySpec(priv.getModulus(), BigInteger.valueOf(65537));

PublicKey publicKey = kf.generatePublic(keySpec);
person Dennis Kriechel    schedule 15.07.2014
comment
Показатель степени открытого ключа для RSA не зафиксирован на уровне 65537, это просто наиболее распространенное значение для него. Поскольку показатель степени закрытого ключа зависит от показателя степени открытого ключа, это решение не будет работать во всех ситуациях. - person Syon; 15.07.2014
comment
@Syon, вы правы в этом, я исправил это, но использование e≠65537 снизит совместимость с существующим оборудованием или программным обеспечением и нарушит соответствие некоторым стандартам или предписаниям органов безопасности, поэтому вы обычно не найдете это. Дополнительная информация здесь: crypto.stackexchange.com/questions/3110/ - person Dennis Kriechel; 15.07.2014
comment
Я согласен с сообщением, которое вы цитируете, если вы создаете новую пару открытого/закрытого ключей. Однако ваш вопрос касается получения открытого ключа из существующего закрытого ключа. Единственный способ сделать это — использовать экспоненту открытого ключа, которая использовалась для создания исходной пары ключей. Использование 65537 во всех ситуациях не будет работать, потому что это может быть не экспонента открытого ключа. Совместимость с существующим оборудованием или программным обеспечением не имеет к этому никакого отношения. - person Syon; 15.07.2014
comment
Что плохого в простом приведении к RSAPrivateKey (конечно, после проверки того, что это является RSAPrivateKey)? - person Maarten Bodewes; 16.07.2014

Вам нужно преобразовать закрытый ключ в RsaPrivateCrtKey. Если приведение успешно, вы можете извлечь открытый ключ. Если бросок терпит неудачу, строго говоря, у вас недостаточно информации.

public static RSAPublicKeySpec getPublicKeySpec(PrivateKey priv) {
    RSAPrivateCrtKey rsaCrtKey = (RSAPrivateCrtKey) priv; // May throw a ClassCastException
    return new RSAPublicKeySpec(rsaCrtKey.getModulus(), rsaCrtKey.getPublicExponent());
}

Если приведение не удается, вы можете попытаться угадать общедоступный показатель степени и проверить свое предположение, используя стандартное отношение RSA (xe)d = x mod N для всех x . Для вашего предположения о e попробуйте случайные значения x в уравнении и посмотрите, всегда ли выполняется соотношение. Однако этот метод может дать только вероятностный ответ.

person President James K. Polk    schedule 15.07.2014