0

I have encrypted a file thanks to OpenSSL with the following command:

openssl smime -encrypt -in myfile.xml -out myfile.p7m -outform DER -binary publicKey.pem

Now, I would to decrypt the file "myfile.p7m" with PHP. Currently, I'm using this code but without success:

$output = "myfile.xml";
$crt = file_get_contents("mycert.crt");
$private = openssl_pkey_get_private (file_get_contents("privateKey.pem"), "password");
openssl_pkcs7_decrypt ("myfile.p7m", $output, $crt, $private);
while($error = openssl_error_string()){
    echo $error.'<br />'.PHP_EOL;
}

At this moment, I get this error:

error:2006D080:BIO routines:BIO_new_file:no such file

I have no idea what this mean.

Can you help me?

PS: I have already decrypted this file with success by using an OpenSSL command:

openssl smime -decrypt -in myfile.p7m -out myfile.xml -inkey 
privateKey.pem -inform DER -passin pass:password

Edit:

Follow the advice of Vladimir Kunschikov, I've used full path for the files. I've replaced "myfile.xml" by "file://c:/wamp/www/test/myfile.xml" and "myfile.p7m" by "file://c:/wamp/www/test/myfile.p7m". Now, I have two another errors:

error:0200107B:system library:fopen:Unknown error
error:2006D002:BIO routines:BIO_new_file:system lib

Edit 2

Thank you Giovani for your response. I replace all paths as you have directed. Now, a new error is appeared!

error:0D0D20CC:asn1 encoding routines:SMIME_read_ASN1:no content type
jww
  • 97,681
  • 90
  • 411
  • 885
Scipius2012
  • 675
  • 1
  • 9
  • 21

3 Answers3

0

try to replace 'file://c:/wamp/www/test/myfile.xml' with 'c:\\wamp\\www\\test\\myfile.xml' and 'file://c:/wamp/www/test/myfile.p7m' with 'c:\\wamp\\www\\test\\myfile.p7m'

Giovani
  • 211
  • 1
  • 7
0

Finally, I've found a solution of this problem. Firstly, the file paths were wrong. I've resolved it by following the proposal of Giovani. For my second error, I've just encoded in base 64 my ".P7M" obtained thanks to my OPENSSL command and I've added an header:

MIME-Version: 1.0
Content-Disposition: attachment; filename="smime.p7m"
Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
Content-Transfer-Encoding: base64

MIIJWAYJKoZIhvcNAQcDoIIJSTCCCUUCAQAxggGnMIIBowIBADCBijB9MQswCQYD
VQQGEwJGUjEVMBMGA1UECAwMUmhvbmVzLUFscGVzMQ0wCwYDVQQHDARMeW9uMQ0w
CwYDVQQKDARZcG9rMQwwCgYDVQQLDANQVmUxDTALBgNVBAMMBFlQVmUxHDAaBgkq
hkiG9w0BCQEWDXlwb2tAeXBvay5jb20CCQCCV/J9OpZ9pjANBgkqhkiG9w0BAQEF
...

In this way, I can decrypt correctly the P7M file.

So, I've noticed by deleting, in my OPENSSL command, the option "-outform DER", I've get a file enable to be decrypted with "openssl_pksc7_decrypt":

openssl smime -encrypt -in myfile.xml -out myfile.p7m -binary publicKey.pem
Scipius2012
  • 675
  • 1
  • 9
  • 21
0

My example of working code to sign the letter to get the balance of the cashier with Yandex Money. Snippet pulled from the code, because please do not criticize severely

(OpenSSL подпись письма на получения баланса по кассе Яндекс Деньги)

 private function _make_message($data)
{
    $tmp_file_msg_raw  = realpath(tempnam('C:\Temp', 'ymr_'));
    $tmp_file_msg_sign = realpath(tempnam('C:\Temp', 'yms_'));
    $EOL     = "\r\n";                // ограничитель строк, некоторые почтовые сервера требуют \n - подобрать опытным путём
    $EOL2    = "\n\n";
    $boundary = md5(uniqid(time()));  // любая строка, которой не будет ниже в потоке данных.

    $fd = fopen($tmp_file_msg_raw, 'w');

    if(!$fd) {
        $error = "Could not open temporary file $tmp_file_msg_raw.";
        return array("status" => false, "error_msg" => $error, "error_no" => 0);
    }

    fwrite($fd, $data);
    fclose($fd);

    if(!@openssl_pkcs7_sign(
        $tmp_file_msg_raw,
        $tmp_file_msg_sign,
        'file://' . $this->_deposit_crt_sign,
        ['file://' . $this->_deposit_key, $this->_config['secret_keyword']],
        [],
        PKCS7_BINARY))
    {
        unlink($tmp_file_msg_raw);
        unlink($tmp_file_msg_sign);
        $error = "Could not sign data: ".openssl_error_string();

        return FALSE;
    }

    $signed_data       = file_get_contents($tmp_file_msg_sign);
    $signed_data_array = explode($EOL2, $signed_data);
    $signed_data       = $signed_data_array[1];
    $signed_data = "-----BEGIN PKCS7-----\n" . $signed_data . "\n-----END PKCS7-----";

    $multipart  = '--' . $boundary . $EOL;
    $multipart .= 'Content-Disposition: form-data; name=smime; filename=smime.p7m' . $EOL;
    $multipart .= 'Content-Type: application/pkcs7-mime' . $EOL;
    $multipart .= $EOL; // раздел между заголовками и телом html-части
    $multipart .= $signed_data;
    $multipart .= $EOL . '--' . $boundary . '--' . $EOL;

    unlink($tmp_file_msg_raw);
    unlink($tmp_file_msg_sign);

    return [
        'headers' => [
            'MIME-Version: 1.0',
            "Content-Type: multipart/form-data; boundary=\"$boundary\"",
        ],
        'body' => $multipart
    ];
}



private function _read_message($data)
{
    $EOL = "\r\n";
    $pkcs7_headers  = 'MIME-Version: 1.0' . $EOL;
    $pkcs7_headers .= 'Content-Disposition: attachment' . $EOL;
    $pkcs7_headers .= 'Content-Type: application/x-pkcs7-mime' . $EOL;
    $pkcs7_headers .= 'Content-Transfer-Encoding: base64' . $EOL;
    $pkcs7_headers .= $EOL;

    $pkcs7_message = $pkcs7_headers . $data;

    $file_pkcs7_msg          = realpath(tempnam('C:\Temp', 'ymm'));
    $file_pkcs7_outfilename  = realpath(tempnam('C:\Temp', 'ymo_'));
    $file_pkcs7_content      = realpath(tempnam('C:\Temp', 'ymc_'));

    $fd_message_response = fopen($file_pkcs7_msg, 'a');

    if(!$fd_message_response) {
        $error = "Could not open temporary file $file_pkcs7_msg.";
        return array("status" => false, "error_msg" => $error, "error_no" => 0);
    }

    fwrite($fd_message_response, $pkcs7_message);
    fclose($fd_message_response);

    if (!@openssl_pkcs7_verify(
        $file_pkcs7_msg,
        PKCS7_BINARY,
        $file_pkcs7_outfilename,
        [$this->_deposit_crt_verify],
        $this->_deposit_crt_verify,
        $file_pkcs7_content))
    {
        // TODO

    };

    $data = file_get_contents($file_pkcs7_content);

    unlink($file_pkcs7_msg);
    unlink($file_pkcs7_outfilename);
    unlink($file_pkcs7_content);

    //while ($msg = openssl_error_string()) echo $msg . "<br />\n";

    return $data;
}


    $data = '<?xml version="1.0" encoding="UTF-8"?><balanceRequest agentId="123456" clientOrderId="1" requestDT="2015-02-17T16:21:22+04:00"/>';
    $data = $this->_make_message($data);

    $url = $this->_config['uri_api_deposition'].'webservice/deposition/api/balance';
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $data['headers']);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data['body']);
    curl_setopt($ch, CURLOPT_VERBOSE, false);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Ymoney CollectMoney');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSLCERT, $this->_ssl_crt);
    curl_setopt($ch, CURLOPT_SSLKEY, $this->_ssl_key);
    curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $this->_config['secret_keyword']);
    curl_setopt($ch, CURLOPT_FORBID_REUSE, TRUE);
    curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE);
    $response = curl_exec($ch);
    //var_dump($response);
    curl_close($ch);

    $msg = $this->_read_message($response);
    var_dump($msg);
Maximus
  • 21
  • 1
  • 4