Вызов openssl_pkey_get_private() для только что созданного закрытого ключа с помощью копирования и вставки

Следующий код создает пару открытый/закрытый ключ, успешно открывает ключ с помощью функции openssl_pkey_get_private() и выводит пару ключей на дисплей. Затем созданный ранее ключ копируется и вставляется обратно в код. Я пытаюсь открыть тот самый закрытый ключ, который работал раньше, а теперь не получается.

Кому интересно, вы можете получить библиотеку по адресу: http://phpseclib.sourceforge.net/index.html

Я использую phpseclib0.3.1, загруженный вчера с сайта исходного кода.

В чем проблема?

Вот полный код. Отраженный результат готов для копирования и замены.

<?php
    set_include_path(get_include_path() . PATH_SEPARATOR . '../libraries/phpseclib');
    include('../libraries/phpseclib/Net/SSH2.php');
    include('../libraries/phpseclib/Crypt/RSA.php');

    $rsa = new Crypt_RSA();

    //$rsa->setPrivateKeyFormat(CRYPT_RSA_PRIVATE_FORMAT_PKCS1);
    //$rsa->setPublicKeyFormat(CRYPT_RSA_PUBLIC_FORMAT_PKCS1);

    //define('CRYPT_RSA_EXPONENT', 65537);
    //define('CRYPT_RSA_SMALLEST_PRIME', 64); // makes it so multi-prime RSA is used
    extract($rsa->createKey()); // == $rsa->createKey(1024) where 1024 is the key size

    echo("<h1 style=\"margin: 0; padding: 0;\"><b><u>Create Keys</u></b></h1><br />");
    echo("\$privatekey2 = \"$privatekey\";<br /><br />");
    echo("\$publickey2 = \"$publickey\";<br /><br />");

    // Decrypt argument
    define("KEY_PASSPHRASE", "");
    $key = openssl_pkey_get_private($privatekey, KEY_PASSPHRASE);
    if (FALSE == $key)
    {
            echo("Failed to get the private key<br />");
            return false;
    }
    else
            echo("Successfully obtained private key.<br />");

    echo("<h1 style=\"margin: 0; padding: 15px 0px 0px 0px;\"><b><u>Read Copy and Pasted Keys</u></b></h1><br />");

    $privatekey2 = "-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQDPyrp/i8WSh8qmGHhTMaKgZeKj9X/Qh+8PrEFa8BqUMyZs61dGN9Cl9fKUq1iz cgRZWQsMPxNTmRvO4gWjBnkr1HQRELLywpfb6ecOin3uPeGY06Kme/DSRfS9YGOxy5rmhzNaCaSG WLdOUUFnQYCKdO5KkvqJSqnFYoLMBfLzEwIDAQABAoGBAJtAd1Ow1O+Ecc7j3ZMbNMzvEwU5+kOO LPni0/nkB5fPF9ithcm7DjPRrWuTEnUQrVssgmql/gSqEvLiQR/rSEA0jtgQ6n2m87SbWNz0DTLp j9jWFHbLFgo865IfssOiiht44FKWyMhQ9/FeH9gBQ0xTbHQIl8Hf/vm59n8wi3AhAkEA6fm6POv/ P+/u0Xz170FVcFVF8HosyPCiHTesdaf3U27Z8nxpPJmybf2+ZH7eJt5HUQAMvsJB75pe7gp7Iiwc awJBAONaCV5kfgmY1xGsRaWme21o1/wxqW8tX3/8glGQ1HeehiEnQ6krlNifrmeH2sBA+BpGhBGJ SovQKZA66TNFrfkCQEQpMAwXZCCoMRZuJOcyTUWQUfOgY/OVxmRkl6Ue7XoszOlLPQ0eaVCJnzF/ lBAWqQf7z7qytKqsegM2onBuEUkCQCmlY5Pz6paNddAZ84Qdk/x9uRrMahIgiJ7kPWb9lb33vvAx xhYmEpT/4y252Bthi1Ec27JuqMYlsodmEzO+LtkCQAVoE1zVkf/pQnUMcTyEE7vDAUouRjiXZHV7 JZq0uOu4ArQFhFBZILIfB9RYbb3Mr1mh1/pt+JipwtMuQ5Nnh7g= -----END RSA PRIVATE KEY-----";
    $publickey2 = "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDPyrp/i8WSh8qmGHhTMaKgZeKj9X/Qh+8PrEFa 8BqUMyZs61dGN9Cl9fKUq1izcgRZWQsMPxNTmRvO4gWjBnkr1HQRELLywpfb6ecOin3uPeGY06Km e/DSRfS9YGOxy5rmhzNaCaSGWLdOUUFnQYCKdO5KkvqJSqnFYoLMBfLzEwIDAQAB -----END PUBLIC KEY-----";
    echo("\$privatekey2 = \"$privatekey2\";<br /><br />");
    $key2 = openssl_pkey_get_private($privatekey2, KEY_PASSPHRASE);
    if (FALSE == $key2)
    {
            echo("Failed to get the copy and pasted key<br />");
            return false;
    }
    else
            echo("Successfully obtained private copy and pasted key.<br />");
?>

Вот пример вывода. Результат здесь служит входными данными (копирование и вставка) для последующего запуска.

Create Keys
$privatekey2 = "-----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQDA5Ehy7A/nZ0CB+xikxods0MzID8OQfJof4nCiKAa7dEv4Z/FA5KpxVSPj+ZQj X+zdm7QLHfqOGTz6ac1eOtmBCmm1VtNh5cxRQwR00GV+PTpuaUjOghL/upcJ8RlC2UAkBMIlw+7O 3rZ+B5ykHSWF2fWyX9uk7N9Ls4LUjDLs7QIDAQABAoGAFp/wG4Kyztqeh2BzYIhkxA+tpV2r+5uR 3GGMAokdWQloC8ftVUY887Qf1JKmnIuY1dl4gcFPbTFqpJiaXQ4cCsFWMjYKcVrTZj38QaWp/ikc 4ZEuYfV6dr2FDUaQaIYlqPvCxmrc7eISHDZEvPNT9LUZcAtxzeJMTIXrbf6T9MECQQD0nH2fGglp FweVVjec/fp2coJuxiI3rtWuLP0Gy3a95d/UbSTxw+gXgVdTTSZy2FfHsTrc4J49jAbTYvVHqPj9 AkEAyd9Zep/jlbGOPIim+UTzvNJsQnJRC4jS1BsYjP/digMkNDQG/nt4R2QZVlTHXM7+abdbeXYA yW3AOPHzP8++sQJBAMJHmK7JKzhAhlFiDQGv50I0aMw6qeq3/hc8vCqtZz4kWcaKeZFcG/avUABl gmgs1GtSpIHSFVyk3rb+HfowhrECQBRFdmHG7n6YrtTLUCEV2HfslWxyuEq1OZ6M/gEirGdwe1E2 rEEfuutIVPcDWmWqb4fEHs5qmBeiCrxtJ2UQAnECQCoUFle3/XAll4sACiV5/Endd7DKCM1g6jQd rtCbvzHh/j6P3sZEGuTZcuDWYmtNVUy6E2HHfNNwztZxVEJZqW4= -----END RSA PRIVATE KEY-----";
$publickey2 = "-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDA5Ehy7A/nZ0CB+xikxods0MzID8OQfJof4nCi KAa7dEv4Z/FA5KpxVSPj+ZQjX+zdm7QLHfqOGTz6ac1eOtmBCmm1VtNh5cxRQwR00GV+PTpuaUjO ghL/upcJ8RlC2UAkBMIlw+7O3rZ+B5ykHSWF2fWyX9uk7N9Ls4LUjDLs7QIDAQAB -----END PUBLIC KEY-----";

Successfully obtained private key.

Read Copy and Pasted Keys
Failed to get the copy and pasted key

ОБНОВЛЕНИЕ 1: похоже, что phpseclib0.3.1 не имеет этого изменения, однако это изменение, по крайней мере, из копирования и вставки, не решает проблему. Я вручную внес изменения в RSA.php (строка 795-804 в версии 0.3.1):

$RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
                                 "Proc-Type: 4,ENCRYPTED\r\n" .
                                 "DEK-Info: DES-EDE3-CBC,$iv\r\n" .
                                 "\r\n" .
                                 chunk_split(base64_encode($des->encrypt($RSAPrivateKey)), 64) .
                                 '-----END RSA PRIVATE KEY-----';
            } else {
                $RSAPrivateKey = "-----BEGIN RSA PRIVATE KEY-----\r\n" .
                                 chunk_split(base64_encode($RSAPrivateKey), 64) .
                                 '-----END RSA PRIVATE KEY-----';

ОБНОВЛЕНИЕ 2: я получил код для работы. Я не уверен, помогло ли включение «, 64» выше или это было необходимо, но то, что действительно помогло, заключалось в замене символа, похожего на пробел, вероятно, из задания копирования и вставки, на «\n» . Как только я это сделал, то вуаля! Вероятно, обе правки были необходимы.


person Sarah Weinberger    schedule 27.03.2013    source источник


Ответы (1)


Вы используете последнюю версию Git phpseclib? Я спрашиваю, потому что некоторое время назад был этот коммит:

https://github.com/phpseclib/phpseclib/commit/e4ccaef7bf74833891386232946d2168a9e2fce2#phpseclib/Crypt/RSA.php

Коммит был вдохновлен https://stackoverflow.com/a/13908986/569976

person Community    schedule 27.03.2013
comment
Я использую phpseclib0.3.1, который кажется последним. Я навел указатель мыши на загрузку phpseclib на вкладке файлов и увидел ссылку на ту же версию. При этом вы, возможно, наткнулись на решение. Я буквально скопировал и вставил $privatekey2 из своего браузера в текстовый редактор, сохранил, загрузил и повторно запустил код. Упомянутая ссылка, как я теперь вспоминаю ранее вчера, говорит, что строки pem должны иметь длину 64 байта. У меня есть одна строка для всего этого, так что это может быть проблемой. Я попробую это в ближайшее время. - person Sarah Weinberger; 27.03.2013
comment
См. обновление 2 выше. Мне нужно было заменить символ, который выглядел как пробел, который, вероятно, был в моем задании копирования и вставки, на символ \n. Включение , 64 само по себе не помогло, хотя включение , 64, вероятно, необходимо, иначе зачем бы строка красиво и аккуратно разбивалась на 64-байтные отрезки. Эта проблема была не очевидной, вовсе не багом в библиотеке. - person Sarah Weinberger; 27.03.2013
comment
Я бы не сказал, что это ошибка в библиотеке, скорее проблема в том, что OpenSSL слишком строг. Чрезмерная строгость вызвала проблемы с тем, что OpenSSL не может читать ключи, сгенерированные другими вещами. И в любом случае эта ошибка была исправлена, как указано в коммите, с которым связана кредитная точка. Это было исправлено три месяца назад. Так уж получилось, что с тех пор не было выпущено ни одного релиза. Отсюда последний комментарий к версии Git. Последняя версия выпуска != последняя версия Git. - person neubert; 27.03.2013