Получить открытый ключ от частного в Java - PullRequest
12 голосов
/ 08 декабря 2011

Я помню, как делал это давным-давно с OpenSSL, но я хочу знать, возможно ли это и как, я никогда не использовал криптографию на Java.

Ответы [ 3 ]

27 голосов
/ 10 октября 2012

Предполагается, что речь идет о закрытых и открытых ключах RSA. Затем, если вы работаете из файла формата PEM, сначала вам нужно прочитать закрытый ключ из файла в объект PrivateKey:

    public PrivateKey readPemRsaPrivateKey(String pemFilename) throws
            java.io.IOException,
            java.security.NoSuchAlgorithmException,
            java.security.spec.InvalidKeySpecException
    {
            String pemString = File2String(pemFilename);

            pemString = pemString.replace("-----BEGIN RSA PRIVATE KEY-----\n", "");
            pemString = pemString.replace("-----END RSA PRIVATE KEY-----", "");

            byte[] decoded = Base64.decodeBase64(pemString);

            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
            KeyFactory kf = KeyFactory.getInstance("RSA");

            return kf.generatePrivate(keySpec);
    }

где File2String что-то вроде:

    private static String File2String(String fileName) throws
            java.io.FileNotFoundException, java.io.IOException
    {
            File file = new File(fileName);

            char[] buffer = null;

            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));

            buffer = new char[(int)file.length()];

            int i = 0;
            int c = bufferedReader.read();

            while (c != -1) {
                    buffer[i++] = (char)c;
                    c = bufferedReader.read();
            }
            return new String(buffer);
    }

Теперь вы можете сгенерировать соответствующий PublicKey с кодом, подобным следующему:

    import java.security.interfaces.RSAPrivateCrtKey;
    import java.security.spec.RSAPublicKeySpec;

...

    PrivateKey myPrivateKey = readPemRsaPrivateKey(myPrivateKeyPemFileName);
    RSAPrivateCrtKey privk = (RSAPrivateCrtKey)myPrivateKey;

    RSAPublicKeySpec publicKeySpec = new java.security.spec.RSAPublicKeySpec(privk.getModulus(), privk.getPublicExponent());

    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey myPublicKey = keyFactory.generatePublic(publicKeySpec);

Кредиты: Как получить публичный ключ RSA с помощью частного ключа?

3 голосов
/ 23 июля 2014

Пожалуйста, убедитесь, что ответ Eli Rosencruft в основном правильный, но порядок модуля и публичного показателя неверен!Это правильное утверждение:

RSAPublicKeySpec publicKeySpec = new java.security.spec.RSAPublicKeySpec(privk.getModulus(), privk.getPublicExponent());
0 голосов
/ 08 декабря 2011

Вы не можете сгенерировать ни один ключ непосредственно из другого.Это математически невозможно.Если у вас есть ключевой объект, содержащий и открытый и закрытый ключи, вы можете извлечь один из них относительно легко.

РЕДАКТИРОВАТЬ, 2017: Многие годыи гораздо лучшее понимание криптовалюты позже, и теперь мне ясно, что этот ответ не совсем корректен.

Цитируя Википедию:

Открытый ключ состоит из модуляn и публичный (или шифровальный) показатель e.Закрытый ключ состоит из модуля n и частного (или расшифровывающего) показателя d, который должен храниться в секрете.p, q и λ (n) также должны храниться в секрете, поскольку они могут использоваться для вычисления d.

Открытый модуль n может быть вычислен как p × q.Единственное, чего не хватает в необработанном закрытом ключе, это e, но это значение обычно выбирается как 65537, и если нет, вы все равно можете вычислить e из d и λ (n).

Однако многие форматы хранения закрытых ключейна самом деле содержат открытый модуль n вместе с другими компонентами, так что вы можете просто сделать прямое извлечение значений.

EDIT, 2018: Все еще получаю отрицательные отзывы за это, и это правильно!Я оставляю этот ответ, чтобы люди могли понять, почему я изначально ошибался, и напомнить себе, что в будущем я не ошибаюсь.

...