/** * Decrypts data stored in an EncryptedData object (data + key). * * @param EncryptedData $encryptedData * @param Priv $key * @throws \Exception * @return string */ public function decrypt(EncryptedData $encryptedData, Priv $key) { $decData = ''; if (!openssl_open($encryptedData->getData(), $decData, $encryptedData->getKey(), $key->asResource())) { throw new \Exception(sprintf("Error decrypting data with private key: %s", openssl_error_string())); } return $decData; }
/** * Decrypt the text in this object * * @param $privateKey String with ascii-armored block, or the return of openssl_get_privatekey * @return String plaintext */ public function getPlaintext($privateKey) { $result = openssl_open($this->encString, $plaintextData, $this->envKeys, $privateKey, $this->algName); if ($result == false) { return false; } return unserialize($plaintextData); }
public function unseal($data, $envelopeKey) { $key = $this->_getKeyResource(); if (!openssl_open($data, $open, $envelopeKey, $key)) { throw new Relax_Openssl_Exception("Error unsealing data: " . openssl_error_string()); } return $open; }
/** * @param string $sealed encrypted value, base64 encoded * @param string $shareKey share key, base64 encoded * @param PrivateKey $private * @return null|string */ public function unseal($sealed, $shareKey, PrivateKey $private) { $unsealed = null; if (openssl_open($this->decode($sealed), $unsealed, $this->decode($shareKey), $private->getResource())) { return $unsealed; } throw new \RuntimeException('Cannot unseal: ' . openssl_error_string()); }
public function decryptMessage() { $input = base64_decode($this->sealedData); $einput = base64_decode($this->envelope); $message = null; // Also passed by reference. openssl_open($input, $message, $einput, $this->privateKey); $this->decrypt = $message; }
/** * decrypt text usgin RSA RC4 algorithm * @param string $encrypted encrypted text * @param array $envelope key data * @return RSA decrypted text * */ function descifrar_RSA_RC4($encrypted, $envelope) { if (!$privateKey = openssl_pkey_get_private('file://' . $_SESSION['APP_PATH'] . 'backend/private.key')) // descifra con la clave privada die('Private Key failed'); $decrypted = ''; if (openssl_open(base64_decode($encrypted), $decrypted, base64_decode($envelope), $privateKey) === FALSE) die('Failed to decrypt data'); // trata de descirar el texto openssl_free_key($privateKey); return $decrypted; }
function mnet_server_strip_encryption($HTTP_RAW_POST_DATA) { $remoteclient = get_mnet_remote_client(); $crypt_parser = new mnet_encxml_parser(); $crypt_parser->parse($HTTP_RAW_POST_DATA); $mnet = get_mnet_environment(); if (!$crypt_parser->payload_encrypted) { return $HTTP_RAW_POST_DATA; } // Make sure we know who we're talking to $host_record_exists = $remoteclient->set_wwwroot($crypt_parser->remote_wwwroot); if (false == $host_record_exists) { throw new mnet_server_exception(7020, 'wrong-wwwroot', $crypt_parser->remote_wwwroot); } // This key is symmetric, and is itself encrypted. Can be decrypted using our private key $key = array_pop($crypt_parser->cipher); // This data is symmetrically encrypted, can be decrypted using the above key $data = array_pop($crypt_parser->cipher); $crypt_parser->free_resource(); $payload = ''; // Initialize payload var // &$payload $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $mnet->get_private_key()); if ($isOpen) { $remoteclient->was_encrypted(); return $payload; } // Decryption failed... let's try our archived keys $openssl_history = get_config('mnet', 'openssl_history'); if(empty($openssl_history)) { $openssl_history = array(); set_config('openssl_history', serialize($openssl_history), 'mnet'); } else { $openssl_history = unserialize($openssl_history); } foreach($openssl_history as $keyset) { $keyresource = openssl_pkey_get_private($keyset['keypair_PEM']); $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $keyresource); if ($isOpen) { // It's an older code, sir, but it checks out $remoteclient->was_encrypted(); $remoteclient->encrypted_to($keyresource); $remoteclient->set_pushkey(); return $payload; } } //If after all that we still couldn't decrypt the message, error out. throw new mnet_server_exception(7023, 'encryption-invalid'); }
public function decodeRequest($data, $profile, &$errorcode) { $privkey = openssl_pkey_get_private($profile->priv_pem); $check = openssl_open(base64_decode($data->request), $decdata, base64_decode($data->enc_key), $privkey); if ($check < 1) { $errorcode = ResponseCode::FORBIDDEN; return false; } $result = json_decode($decdata); if ($result === false) { $errorcode = ResponseCode::BAD_REQUEST; return false; } return $result; }
/** * Decrypt string returned by crypt method. * * @param string * @param string * @return string */ public static function decrypt($data, $private) { self::checkAvailability(); $arr = @unserialize(base64_decode($data)); if (!$arr) { throw new \RuntimeException('Encrypted data can not be unserialized.'); } if (count($arr) !== 2) { throw new \RuntimeException(sprintf('Encoded data must have 2 elements in array afted deserialization. %s found.', count($arr))); } $private = openssl_pkey_get_private($private); if (!$private) { throw new \RuntimeException('Private key can not be loaded.'); } $decrypted = ''; if (!openssl_open($arr[1], $decrypted, $arr[0], $private)) { throw new \RuntimeException('Encrypted data can not be decrypted.'); } return $decrypted; }
/** * {@inheritdoc} */ public function decrypt($cipherText) { $elements = explode('#', $cipherText); if (sizeof($elements) != 4 || $elements[0] != 'fCryptography::public') { throw new ProgrammerException('The cipher text provided does not appear to have been encrypted using fCryptography::publicKeyEncrypt() or %s#%s()', substr(strrchr(__CLASS__, '\\'), 1), __FUNCTION__); } $encryptedKey = base64_decode($elements[1]); $cipherText = base64_decode($elements[2]); $providedHmac = $elements[3]; $plainText = ''; $result = openssl_open($cipherText, $plainText, $encryptedKey, $this->privateKeyResource); if ($result === false) { throw new EnvironmentException('Unknown error occurred while decrypting the cipher text provided'); } $hmac = hash_hmac('sha1', $encryptedKey . $cipherText, $plainText); // By verifying the HMAC we ensure the integrity of the data if ($hmac !== $providedHmac) { throw new ValidationException('The cipher text provided appears to have been tampered with or corrupted'); } return $plainText; }
function qs_queryQS($action, $data = '', $fast = false) { global $qs_public_key; // generate new private key $key = openssl_pkey_new(); openssl_pkey_export($key, $private_key); $public_key = openssl_pkey_get_details($key); $public_key = $public_key["key"]; $message = qs_base64_serialize(array('key' => $public_key, 'data' => $data)); openssl_seal($message, $message, $server_key, array($qs_public_key)); $message = qs_base64_serialize(array('key' => $server_key[0], 'data' => $message)); $data = "message=" . $message; // connect to qts if ($fast) { $fp = fsockopen('www.qianqin.de', 80, $errno, $errstr, QS_FAST_TIMEOUT); stream_set_timeout($fp, QS_FAST_TIMEOUT); } else { $fp = fsockopen('www.qianqin.de', 80); } if (!$fp) { return false; } fputs($fp, "POST /qtranslate/services/{$action} HTTP/1.1\r\n"); fputs($fp, "Host: www.qianqin.de\r\n"); fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); fputs($fp, "Content-length: " . strlen($data) . "\r\n"); fputs($fp, "Connection: close\r\n\r\n"); fputs($fp, $data); $res = ''; while (!feof($fp)) { $res .= fgets($fp, 128); } // check for timeout $info = stream_get_meta_data($fp); if ($info['timed_out']) { return false; } fclose($fp); preg_match("#^Content-Length:\\s*([0-9]+)\\s*\$#ism", $res, $match); $content_length = $match[1]; $content = substr($res, -$content_length, $content_length); $debug = $content; $content = qs_base64_unserialize($content); openssl_open($content['data'], $content, $content['key'], $private_key); if ($content === false) { echo "<pre>DEBUG:\n"; echo $debug; echo "</pre>"; } openssl_free_key($key); return qs_cleanup(qs_base64_unserialize($content), $action); }
/** * @param $encKeyFile * @param $shareKey * @param $privateKey * @return mixed * @throws MultiKeyDecryptException */ public function multiKeyDecrypt($encKeyFile, $shareKey, $privateKey) { if (!$encKeyFile) { throw new MultiKeyDecryptException('Cannot multikey decrypt empty plain content'); } if (openssl_open($encKeyFile, $plainContent, $shareKey, $privateKey)) { return $plainContent; } else { throw new MultiKeyDecryptException('multikeydecrypt with share key failed:' . openssl_error_string()); } }
/** * Send the request to the server - decode and return the response * * @param object $mnet_peer A mnet_peer object with details of the * remote host we're connecting to * @return mixed A PHP variable, as returned by the * remote function */ function send($mnet_peer) { global $CFG, $MNET; $this->uri = $mnet_peer->wwwroot . $mnet_peer->application->xmlrpc_server_url; // Initialize with the target URL $ch = curl_init($this->uri); $system_methods = array('system/listMethods', 'system/methodSignature', 'system/methodHelp', 'system/listServices'); if (in_array($this->method, $system_methods)) { // Executing any system method is permitted. } else { $id_list = $mnet_peer->id; if (!empty($CFG->mnet_all_hosts_id)) { $id_list .= ', ' . $CFG->mnet_all_hosts_id; } // At this point, we don't care if the remote host implements the // method we're trying to call. We just want to know that: // 1. The method belongs to some service, as far as OUR host knows // 2. We are allowed to subscribe to that service on this mnet_peer // Find methods that we subscribe to on this host $sql = "\n SELECT\n r.id\n FROM\n {$CFG->prefix}mnet_rpc r,\n {$CFG->prefix}mnet_service2rpc s2r,\n {$CFG->prefix}mnet_host2service h2s\n WHERE\n r.xmlrpc_path = '{$this->method}' AND\n s2r.rpcid = r.id AND\n s2r.serviceid = h2s.serviceid AND\n h2s.subscribe = '1' AND\n h2s.hostid in ({$id_list})"; if (!record_exists_sql($sql)) { global $USER; $this->error[] = '7:User with ID ' . $USER->id . ' attempted to call unauthorised method ' . $this->method . ' on host ' . $mnet_peer->wwwroot; return false; } } $this->requesttext = xmlrpc_encode_request($this->method, $this->params, array("encoding" => "utf-8", "escaping" => "markup")); $rq = $this->requesttext; $rq = mnet_sign_message($this->requesttext); $this->signedrequest = $rq; $rq = mnet_encrypt_message($rq, $mnet_peer->public_key); $this->encryptedrequest = $rq; curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_USERAGENT, 'Moodle'); curl_setopt($ch, CURLOPT_POSTFIELDS, $rq); curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: text/xml charset=UTF-8")); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); $timestamp_send = time(); $this->rawresponse = curl_exec($ch); $timestamp_receive = time(); if ($this->rawresponse === false) { $this->error[] = curl_errno($ch) . ':' . curl_error($ch); return false; } $this->rawresponse = trim($this->rawresponse); $mnet_peer->touch(); $crypt_parser = new mnet_encxml_parser(); $crypt_parser->parse($this->rawresponse); if ($crypt_parser->payload_encrypted) { $key = array_pop($crypt_parser->cipher); $data = array_pop($crypt_parser->cipher); $crypt_parser->free_resource(); // Initialize payload var $payload = ''; // &$payload $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $MNET->get_private_key()); if (!$isOpen) { // Decryption failed... let's try our archived keys $openssl_history = get_config('mnet', 'openssl_history'); if (empty($openssl_history)) { $openssl_history = array(); set_config('openssl_history', serialize($openssl_history), 'mnet'); } else { $openssl_history = unserialize($openssl_history); } foreach ($openssl_history as $keyset) { $keyresource = openssl_pkey_get_private($keyset['keypair_PEM']); $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $keyresource); if ($isOpen) { // It's an older code, sir, but it checks out break; } } } if (!$isOpen) { trigger_error("None of our keys could open the payload from host {$mnet_peer->wwwroot} with id {$mnet_peer->id}."); $this->error[] = '3:No key match'; return false; } if (strpos(substr($payload, 0, 100), '<signedMessage>')) { $sig_parser = new mnet_encxml_parser(); $sig_parser->parse($payload); } else { $this->error[] = '2:Payload not signed: ' . $payload; return false; } } else { if (!empty($crypt_parser->remoteerror)) { $this->error[] = '4: remote server error: ' . $crypt_parser->remoteerror; } else { if (!empty($crypt_parser->error)) { $crypt_parser_error = $crypt_parser->error[0]; $message = '3:XML Parse error in payload: ' . $crypt_parser_error['string'] . "\n"; if (array_key_exists('lineno', $crypt_parser_error)) { $message .= 'At line number: ' . $crypt_parser_error['lineno'] . "\n"; } if (array_key_exists('line', $crypt_parser_error)) { $message .= 'Which reads: ' . $crypt_parser_error['line'] . "\n"; } $this->error[] = $message; } else { $this->error[] = '1:Payload not encrypted '; } } $crypt_parser->free_resource(); return false; } // Margin of error is the time it took the request to complete. $margin_of_error = $timestamp_receive - $timestamp_send; // Guess the time gap between sending the request and the remote machine // executing the time() function. Marginally better than nothing. $hysteresis = $margin_of_error / 2; $remote_timestamp = $sig_parser->remote_timestamp - $hysteresis; $time_offset = $remote_timestamp - $timestamp_send; if ($time_offset > 0) { $threshold = get_config('mnet', 'drift_threshold'); if (empty($threshold)) { // We decided 15 seconds was a pretty good arbitrary threshold // for time-drift between servers, but you can customize this in // the config_plugins table. It's not advised though. set_config('drift_threshold', 15, 'mnet'); $threshold = 15; } if ($time_offset > $threshold) { $this->error[] = '6:Time gap with ' . $mnet_peer->name . ' (' . $time_offset . ' seconds) is greater than the permitted maximum of ' . $threshold . ' seconds'; return false; } } $this->xmlrpcresponse = base64_decode($sig_parser->data_object); $this->response = xmlrpc_decode($this->xmlrpcresponse); curl_close($ch); // xmlrpc errors are pushed onto the $this->error stack if (is_array($this->response) && array_key_exists('faultCode', $this->response)) { // The faultCode 7025 means we tried to connect with an old SSL key // The faultString is the new key - let's save it and try again // The re_key attribute stops us from getting into a loop if ($this->response['faultCode'] == 7025 && empty($mnet_peer->re_key)) { $record = new stdClass(); $record->id = $mnet_peer->id; if ($this->response['faultString'] == clean_param($this->response['faultString'], PARAM_PEM)) { $record->public_key = $this->response['faultString']; $details = openssl_x509_parse($record->public_key); if (is_array($details) && isset($details['validTo_time_t'])) { $record->public_key_expires = $details['validTo_time_t']; update_record('mnet_host', $record); $mnet_peer2 = new mnet_peer(); $mnet_peer2->set_id($record->id); $mnet_peer2->re_key = true; $this->send($mnet_peer2); } else { $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString']; } } else { $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString']; } } else { if (!empty($CFG->mnet_rpcdebug)) { $guidance = get_string('error' . $this->response['faultCode'], 'mnet'); } else { $guidance = ''; } $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString']; } } // ok, it's signed, but is it signed with the right certificate ? // do this *after* we check for an out of date key $verified = openssl_verify($this->xmlrpcresponse, base64_decode($sig_parser->signature), $mnet_peer->public_key); if ($verified != 1) { $this->error[] = 'Invalid signature'; } return empty($this->error); }
/** * Unseals the given envelope. * * @param string $envelope The envelope to unseal. * @param string $envelopeKey The envelope hash key. * @param string $cipherMethod The cipher method used to seal the message. * @param string $iv The optional initialization vector for some cipher methods. * @return string The unsealed message. * @since 0.3 */ public function unseal(string $envelope, string $envelopeKey, string $cipherMethod = null, string $iv = '') : string { OpenSSL::resetErrors(); $paddedIV = InitVector::pad($iv); if (@openssl_open($envelope, $message, $envelopeKey, $this->resource, $cipherMethod, $paddedIV) === false) { // @codeCoverageIgnoreStart throw new OpenSSLException(OpenSSL::getErrors(), 'Could not unseal envelope.'); // @codeCoverageIgnoreEnd } return $message; }
$sub->connect($config->pubOn[0]); $sub->subscribe("H"); $sub->subscribe($identity); $sub->on('messages', function ($msg) use($identity, $privateKey) { try { echo 'Received: ' . json_encode($msg) . PHP_EOL; if ($msg[0] == "H") { return; } // Expect messages to have a length of 3 if (count($msg) != 3) { throw new InvalidArgumentException('Incorrect Message Length'); } // Message will be channel, key, message if ($msg[0] != $identity) { throw new InvalidArgumentException('Channel does not match'); } // Decrypt the message using our private key $opened = null; $key = base64_decode($msg[1]); $message = base64_decode($msg[2]); if (!openssl_open($message, $opened, $key, $privateKey)) { throw new \Xibo\XMR\PlayerActionException('Encryption Error'); } echo 'Message: ' . $opened; } catch (InvalidArgumentException $e) { echo $e->getMessage(); } }); $loop->run(); openssl_free_key($privateKey);
public static function unseal($sealed, $privateKey) { list($sealed, $Xevk) = explode('@', $sealed); openssl_open(base64_decode($sealed), $opened, base64_decode($Xevk), $privateKey) or die(openssl_error_string()); return $opened; }
/** * Decrypts ciphertext encrypted using public-key encryption via ::publicKeyEncrypt() * * A public key (X.509 certificate) is required for encryption and a * private key (PEM) is required for decryption. * * @throws fValidationException When the ciphertext appears to be corrupted * * @param string $ciphertext The content to be decrypted * @param string $private_key_file The path to a PEM-encoded private key * @param string $password The password for the private key * @return string The decrypted plaintext */ public static function publicKeyDecrypt($ciphertext, $private_key_file, $password) { self::verifyPublicKeyEnvironment(); $private_key_resource = self::createPrivateKeyResource($private_key_file, $password); $elements = explode('#', $ciphertext); // We need to make sure this ciphertext came from here, otherwise we are gonna have issues decrypting it if (sizeof($elements) != 4 || $elements[0] != 'fCryptography::public') { throw new fProgrammerException('The ciphertext provided does not appear to have been encrypted using %s', __CLASS__ . '::publicKeyEncrypt()'); } $encrypted_key = base64_decode($elements[1]); $ciphertext = base64_decode($elements[2]); $provided_hmac = $elements[3]; $plaintext = ''; $result = openssl_open($ciphertext, $plaintext, $encrypted_key, $private_key_resource); openssl_free_key($private_key_resource); if ($result === FALSE) { throw new fEnvironmentException('There was an unknown error decrypting the ciphertext provided'); } $hmac = hash_hmac('sha1', $encrypted_key . $ciphertext, $plaintext); // By verifying the HMAC we ensure the integrity of the data if ($hmac != $provided_hmac) { throw new fValidationException('The ciphertext provided appears to have been tampered with or corrupted'); } return $plaintext; }
<?php $data = "openssl_open() test"; $pub_key = "file://" . dirname(__FILE__) . "/public.key"; $priv_key = "file://" . dirname(__FILE__) . "/private.key"; $wrong = "wrong"; openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key, $pub_key)); openssl_open($sealed, $output, $ekeys[0], $priv_key); var_dump($output); openssl_open($sealed, $output2, $ekeys[1], $wrong); var_dump($output2); openssl_open($sealed, $output3, $ekeys[2], $priv_key); var_dump($output3); openssl_open($sealed, $output4, $wrong, $priv_key); var_dump($output4);
/** * Strip the encryption (XML-ENC) and signature (XML-SIG) wrappers and return the XML-RPC payload * * IF COMMUNICATION TAKES PLACE OVER UNENCRYPTED HTTP: * The payload will have been encrypted with a symmetric key. This key will * itself have been encrypted using your public key. The key is decrypted using * your private key, and then used to decrypt the XML payload. * * IF COMMUNICATION TAKES PLACE OVER UNENCRYPTED HTTP *OR* ENCRYPTED HTTPS: * In either case, there will be an XML wrapper which contains your XML-RPC doc * as an object element, a signature for that doc, and various standards- * compliant info to aid in verifying the signature. * * This function parses the encryption wrapper, decrypts the contents, parses * the signature wrapper, and if the signature matches the payload, it returns * the payload, which should be an XML-RPC request. * If there is an error, or the signatures don't match, it echoes an XML-RPC * error and exits. * * See the W3C's {@link http://www.w3.org/TR/xmlenc-core/ XML Encryption Syntax and Processing} * and {@link http://www.w3.org/TR/2001/PR-xmldsig-core-20010820/ XML-Signature Syntax and Processing} * guidelines for more detail on the XML. * * -----XML-Envelope--------------------------------- * | | * | Encrypted-Symmetric-key---------------- | * | |_____________________________________| | * | | * | Encrypted data------------------------- | * | | | | * | | -XML-Envelope------------------ | | * | | | | | | * | | | --Signature------------- | | | * | | | |______________________| | | | * | | | | | | * | | | --Signed-Payload-------- | | | * | | | | | | | | * | | | | XML-RPC Request | | | | * | | | |______________________| | | | * | | | | | | * | | |_____________________________| | | * | |_____________________________________| | * | | * |________________________________________________| * * @uses $db * @param string $HTTP_RAW_POST_DATA The XML that the client sent * @return string The XMLRPC payload. */ function mnet_server_strip_wrappers($HTTP_RAW_POST_DATA) { global $MNET, $MNET_REMOTE_CLIENT; if (isset($_SERVER)) { $crypt_parser = new mnet_encxml_parser(); $crypt_parser->parse($HTTP_RAW_POST_DATA); // Make sure we know who we're talking to $host_record_exists = $MNET_REMOTE_CLIENT->set_wwwroot($crypt_parser->remote_wwwroot); if (false == $host_record_exists) { exit(mnet_server_fault(7020, 'wrong-wwwroot', $crypt_parser->remote_wwwroot)); } if ($crypt_parser->payload_encrypted) { $key = array_pop($crypt_parser->cipher); // This key is Symmetric $data = array_pop($crypt_parser->cipher); $crypt_parser->free_resource(); $payload = ''; // Initialize payload var $push_current_key = false; // True if we need to push a fresh key to the peer // &$payload $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $MNET->get_private_key()); if (!$isOpen) { // Decryption failed... let's try our archived keys $openssl_history = get_config('mnet', 'openssl_history'); if (empty($openssl_history)) { $openssl_history = array(); set_config('openssl_history', serialize($openssl_history), 'mnet'); } else { $openssl_history = unserialize($openssl_history); } foreach ($openssl_history as $keyset) { $keyresource = openssl_pkey_get_private($keyset['keypair_PEM']); $isOpen = openssl_open(base64_decode($data), $payload, base64_decode($key), $keyresource); if ($isOpen) { // It's an older code, sir, but it checks out $push_current_key = true; break; } } } if (!$isOpen) { exit(mnet_server_fault(7023, 'encryption-invalid')); } if (strpos(substr($payload, 0, 100), '<signedMessage>')) { $MNET_REMOTE_CLIENT->was_signed(); $sig_parser = new mnet_encxml_parser(); $sig_parser->parse($payload); } else { exit(mnet_server_fault(7022, 'verifysignature-error')); } } else { exit(mnet_server_fault(7024, 'payload-not-encrypted')); } unset($payload); // if the peer used one of our public keys that have expired, we will // return a signed/encrypted error message with our new public key if ($push_current_key) { // NOTE: Here, we use the 'mnet_server_fault_xml' to avoid // get_string being called on our public_key exit(mnet_server_fault_xml(7025, $MNET->public_key, $keyresource)); } /** * Get the certificate (i.e. public key) from the remote server. */ $certificate = $MNET_REMOTE_CLIENT->public_key; if ($certificate == false) { exit(mnet_server_fault(709, 'nosuchpublickey')); } $payload = base64_decode($sig_parser->data_object); // Does the signature match the data and the public cert? $signature_verified = openssl_verify($payload, base64_decode($sig_parser->signature), $certificate); if ($signature_verified == 0) { // $signature was not generated for $payload using $certificate // Get the key the remote peer is currently publishing: $currkey = mnet_get_public_key($MNET_REMOTE_CLIENT->wwwroot, $MNET_REMOTE_CLIENT->application->xmlrpc_server_url); // If the key the remote peer is currently publishing is different to $certificate if ($currkey != $certificate) { // If we can't get the server's new key through trusted means, exit. if (!$MNET_REMOTE_CLIENT->refresh_key()) { exit(mnet_server_fault(7026, 'verifysignature-invalid')); } // If we did manage to re-key, try to verify the signature again against the new public key. $certificate = $MNET_REMOTE_CLIENT->public_key; $signature_verified = openssl_verify($payload, base64_decode($sig_parser->signature), $certificate); } } if ($signature_verified == 1) { $MNET_REMOTE_CLIENT->touch(); } elseif ($signature_verified == 0) { exit(mnet_server_fault(710, 'verifysignature-invalid')); } else { exit(mnet_server_fault(711, 'verifysignature-error')); } $sig_parser->free_resource(); return $payload; } else { exit(mnet_server_fault(712, "phperror")); } }
<?php $data = "openssl_seal() test"; $cipher = 'AES-128-CBC'; $pub_key = "file://" . dirname(__FILE__) . "/public.key"; $priv_key = "file://" . dirname(__FILE__) . "/private.key"; openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key), $cipher); openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key), 'sparkles', $iv); openssl_seal($data, $sealed, $ekeys, array($pub_key, $pub_key), $cipher, $iv); openssl_open($sealed, $decrypted, $ekeys[0], $priv_key, $cipher, $iv); echo $decrypted;
public static function open($sealedData, &$openData, $envKey, PKey $key) { $return = openssl_open($sealedData, $openData, $envKey, $key->getResource()); self::handleReturn($return); return $return; }
/** * Asymmetrically encrypt a file using multiple public keys * @param string $encryptedContent * @param string $shareKey * @param mixed $privateKey * @throws \OCA\Files_Encryption\Exception\MultiKeyDecryptException if decryption failed * @internal param string $plainContent contains decrypted content * @return string $plainContent decrypted string * @note symmetricDecryptFileContent() can be used to decrypt files created using this method * * This function decrypts a file */ public static function multiKeyDecrypt($encryptedContent, $shareKey, $privateKey) { if (!$encryptedContent) { throw new Exception\MultiKeyDecryptException('Cannot mutliKeyDecrypt empty plain content', Exception\MultiKeyDecryptException::EMPTY_DATA); } if (openssl_open($encryptedContent, $plainContent, $shareKey, $privateKey)) { return $plainContent; } else { throw new Exception\MultiKeyDecryptException('multiKeyDecrypt with share-key' . $shareKey . 'failed: ' . openssl_error_string(), Exception\MultiKeyDecryptException::OPENSSL_OPEN_FAILED); } }
/** * Decrypt a message with the private key * * @param string $cypherText * The encrypted text * @return mixed * The original data * * @throws SSLEncryptionException */ public function decrypt($cypherText) { $envelope = json_decode(base64_decode($cypherText)); if (!is_object($envelope) || empty($envelope->key) || empty($envelope->message)) { throw new SSLEncryptionException('Encrypted message is not understood'); } $key = base64_decode($envelope->key); $message = base64_decode($envelope->message); $decrypted = ''; $result = openssl_open($message, $decrypted, $key, $this->privateKey); if ($result === FALSE) { throw new SSLEncryptionException('Unable to decrypt a message: ' . openssl_error_string()); } return json_decode($decrypted); }
/** * Defined by Zend_Filter_Interface * * Decrypts the file $value with the defined settings * * @param string $value Content to decrypt * @return string The decrypted content * @throws Zend_Filter_Exception */ public function decrypt($value) { $decrypted = ""; $envelope = current($this->getEnvelopeKey()); if (count($this->_keys['private']) !== 1) { require_once 'Zend/Filter/Exception.php'; throw new Zend_Filter_Exception('Openssl can only decrypt with one private key'); } if (empty($envelope)) { require_once 'Zend/Filter/Exception.php'; throw new Zend_Filter_Exception('Openssl can only decrypt with one envelope key'); } foreach ($this->_keys['private'] as $key => $cert) { $keys = openssl_pkey_get_private($cert, $this->getPassphrase()); } $crypt = openssl_open($value, $decrypted, $envelope, $keys); openssl_free_key($keys); if ($crypt === false) { require_once 'Zend/Filter/Exception.php'; throw new Zend_Filter_Exception('Openssl was not able to decrypt you content with the given options'); } return $decrypted; }
function test_openssl_seal() { $privkey = openssl_pkey_new(); VERIFY($privkey != null); $csr = openssl_csr_new(null, $privkey); VERIFY($csr != null); $pubkey = openssl_csr_get_public_key($csr); VERIFY($pubkey != null); $data = "some secret messages"; VERIFY(openssl_seal($data, $sealed, $ekeys, array($pubkey))); VERIFY(strlen($sealed) > 0); VS(count($ekeys), 1); VERIFY(strlen($ekeys[0]) > 0); VERIFY(openssl_open($sealed, $open_data, $ekeys[0], $privkey)); VS($open_data, $data); VERIFY(openssl_open($sealed, $open_data, $ekeys[0], $privkey, 'RC4')); VS($open_data, $data); VERIFY(openssl_seal($data, $sealed, $ekeys, array($pubkey), 'AES-256-ECB')); VERIFY(strlen($sealed) > 0); VS(count($ekeys), 1); VERIFY(strlen($ekeys[0]) > 0); VERIFY(openssl_open($sealed, $open_data, $ekeys[0], $privkey, 'AES-256-ECB')); VS($open_data, $data); }
/** * * @param string $data * @param string $privateKey * @return string * @throws \InvalidArgumentException */ public function decryptData($data, $privateKey) { if (!is_string($privateKey)) { throw new \InvalidArgumentException('Private key should be given as string', 1300211696); } list($envelopeKey, $cryptedData) = explode(':', $data, 2); $envelopeKey = base64_decode($envelopeKey); $cryptedData = base64_decode($cryptedData); openssl_open($cryptedData, $decrypted, $envelopeKey, $privateKey); return $decrypted; }
/** * Decrypt some data using our private key and an auxiliary symmetric key. * The symmetric key encrypted the data, and then was itself encrypted with * our public key. * This is because asymmetric keys can only safely be used to encrypt * relatively short messages. * * @param string $data * @param string $key * @param bool $oldkeyok If true, we will simply return the data rather * than complaining about the key being old (if * we could decrypt it with an older key) * @return string * @access public */ public function openssl_open($data, $key, $oldkeyok = false) { $payload = ''; $isOpen = openssl_open($data, $payload, $key, $this->keypair['privatekey']); if (!empty($isOpen)) { return $payload; } else { // Decryption failed... let's try our archived keys $openssl_history = $this->get_history(); foreach ($openssl_history as $keyset) { $keyresource = openssl_pkey_get_private($keyset['keypair_PEM']); $isOpen = openssl_open($data, $payload, $key, $keyresource); if ($isOpen) { // It's an older code, sir, but it checks out if ($oldkeyok) { return $payload; } else { // We notify the remote host that the key has changed throw new CryptException($this->keypair['certificate'], 7025); } } } } throw new CryptException('We know nothing about the key used to encrypt this message', 7025); }
/** * Send the request to the server - decode and return the response * * @param object $mnet_peer A mnet_peer object with details of the * remote host we're connecting to * @return mixed A PHP variable, as returned by the * remote function */ function send($mnet_peer) { global $CFG, $DB; if (!$this->permission_to_call($mnet_peer)) { mnet_debug("tried and wasn't allowed to call a method on {$mnet_peer->wwwroot}"); return false; } $this->requesttext = xmlrpc_encode_request($this->method, $this->params, array("encoding" => "utf-8", "escaping" => "markup")); $this->signedrequest = mnet_sign_message($this->requesttext); $this->encryptedrequest = mnet_encrypt_message($this->signedrequest, $mnet_peer->public_key); $httprequest = $this->prepare_http_request($mnet_peer); curl_setopt($httprequest, CURLOPT_POSTFIELDS, $this->encryptedrequest); $timestamp_send = time(); mnet_debug("about to send the curl request"); $this->rawresponse = curl_exec($httprequest); mnet_debug("managed to complete a curl request"); $timestamp_receive = time(); if ($this->rawresponse === false) { $this->error[] = curl_errno($httprequest) . ':' . curl_error($httprequest); return false; } curl_close($httprequest); $this->rawresponse = trim($this->rawresponse); $mnet_peer->touch(); $crypt_parser = new mnet_encxml_parser(); $crypt_parser->parse($this->rawresponse); // If we couldn't parse the message, or it doesn't seem to have encrypted contents, // give the most specific error msg available & return if (!$crypt_parser->payload_encrypted) { if (!empty($crypt_parser->remoteerror)) { $this->error[] = '4: remote server error: ' . $crypt_parser->remoteerror; } else { if (!empty($crypt_parser->error)) { $crypt_parser_error = $crypt_parser->error[0]; $message = '3:XML Parse error in payload: ' . $crypt_parser_error['string'] . "\n"; if (array_key_exists('lineno', $crypt_parser_error)) { $message .= 'At line number: ' . $crypt_parser_error['lineno'] . "\n"; } if (array_key_exists('line', $crypt_parser_error)) { $message .= 'Which reads: ' . $crypt_parser_error['line'] . "\n"; } $this->error[] = $message; } else { $this->error[] = '1:Payload not encrypted '; } } $crypt_parser->free_resource(); return false; } $key = array_pop($crypt_parser->cipher); $data = array_pop($crypt_parser->cipher); $crypt_parser->free_resource(); // Initialize payload var $decryptedenvelope = ''; // &$decryptedenvelope $isOpen = openssl_open(base64_decode($data), $decryptedenvelope, base64_decode($key), $this->mnet->get_private_key()); if (!$isOpen) { // Decryption failed... let's try our archived keys $openssl_history = get_config('mnet', 'openssl_history'); if (empty($openssl_history)) { $openssl_history = array(); set_config('openssl_history', serialize($openssl_history), 'mnet'); } else { $openssl_history = unserialize($openssl_history); } foreach ($openssl_history as $keyset) { $keyresource = openssl_pkey_get_private($keyset['keypair_PEM']); $isOpen = openssl_open(base64_decode($data), $decryptedenvelope, base64_decode($key), $keyresource); if ($isOpen) { // It's an older code, sir, but it checks out break; } } } if (!$isOpen) { trigger_error("None of our keys could open the payload from host {$mnet_peer->wwwroot} with id {$mnet_peer->id}."); $this->error[] = '3:No key match'; return false; } if (strpos(substr($decryptedenvelope, 0, 100), '<signedMessage>')) { $sig_parser = new mnet_encxml_parser(); $sig_parser->parse($decryptedenvelope); } else { $this->error[] = '2:Payload not signed: ' . $decryptedenvelope; return false; } // Margin of error is the time it took the request to complete. $margin_of_error = $timestamp_receive - $timestamp_send; // Guess the time gap between sending the request and the remote machine // executing the time() function. Marginally better than nothing. $hysteresis = $margin_of_error / 2; $remote_timestamp = $sig_parser->remote_timestamp - $hysteresis; $time_offset = $remote_timestamp - $timestamp_send; if ($time_offset > 0) { $threshold = get_config('mnet', 'drift_threshold'); if (empty($threshold)) { // We decided 15 seconds was a pretty good arbitrary threshold // for time-drift between servers, but you can customize this in // the config_plugins table. It's not advised though. set_config('drift_threshold', 15, 'mnet'); $threshold = 15; } if ($time_offset > $threshold) { $this->error[] = '6:Time gap with ' . $mnet_peer->name . ' (' . $time_offset . ' seconds) is greater than the permitted maximum of ' . $threshold . ' seconds'; return false; } } $this->xmlrpcresponse = base64_decode($sig_parser->data_object); $this->response = xmlrpc_decode($this->xmlrpcresponse); // xmlrpc errors are pushed onto the $this->error stack if (is_array($this->response) && array_key_exists('faultCode', $this->response)) { // The faultCode 7025 means we tried to connect with an old SSL key // The faultString is the new key - let's save it and try again // The re_key attribute stops us from getting into a loop if ($this->response['faultCode'] == 7025 && empty($mnet_peer->re_key)) { mnet_debug('recieved an old-key fault, so trying to get the new key and update our records'); // If the new certificate doesn't come thru clean_param() unmolested, error out if ($this->response['faultString'] != clean_param($this->response['faultString'], PARAM_PEM)) { $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString']; } $record = new stdClass(); $record->id = $mnet_peer->id; $record->public_key = $this->response['faultString']; $details = openssl_x509_parse($record->public_key); if (!isset($details['validTo_time_t'])) { $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString']; } $record->public_key_expires = $details['validTo_time_t']; $DB->update_record('mnet_host', $record); // Create a new peer object populated with the new info & try re-sending the request $rekeyed_mnet_peer = new mnet_peer(); $rekeyed_mnet_peer->set_id($record->id); $rekeyed_mnet_peer->re_key = true; return $this->send($rekeyed_mnet_peer); } if (!empty($CFG->mnet_rpcdebug)) { if (get_string_manager()->string_exists('error' . $this->response['faultCode'], 'mnet')) { $guidance = get_string('error' . $this->response['faultCode'], 'mnet'); } else { $guidance = ''; } } else { $guidance = ''; } $this->error[] = $this->response['faultCode'] . " : " . $this->response['faultString'] . "\n" . $guidance; } // ok, it's signed, but is it signed with the right certificate ? // do this *after* we check for an out of date key if (!openssl_verify($this->xmlrpcresponse, base64_decode($sig_parser->signature), $mnet_peer->public_key)) { $this->error[] = 'Invalid signature'; } return empty($this->error); }
/** * Defined by Zend_Filter_Interface * * Decrypts $value with the defined settings * * @param string $value Content to decrypt * @return string The decrypted content * @throws Zend_Filter_Exception */ public function decrypt($value) { $decrypted = ""; $envelope = current($this->getEnvelopeKey()); if (count($this->_keys['private']) !== 1) { require_once 'Zend/Filter/Exception.php'; throw new Zend_Filter_Exception('Please give a private key for decryption with Openssl'); } if (!$this->_package && empty($envelope)) { require_once 'Zend/Filter/Exception.php'; throw new Zend_Filter_Exception('Please give a envelope key for decryption with Openssl'); } foreach ($this->_keys['private'] as $key => $cert) { $keys = openssl_pkey_get_private($cert, $this->getPassphrase()); } if ($this->_package) { $details = openssl_pkey_get_details($keys); if ($details !== false) { $fingerprint = md5($details['key']); } else { $fingerprint = md5("ZendFramework"); } $count = unpack('ncount', $value); $count = $count['count']; $length = 2; for ($i = $count; $i > 0; --$i) { $header = unpack('H32print/nsize', substr($value, $length, 18)); $length += 18; if ($header['print'] == $fingerprint) { $envelope = substr($value, $length, $header['size']); } $length += $header['size']; } // remainder of string is the value to decrypt $value = substr($value, $length); } $crypt = openssl_open($value, $decrypted, $envelope, $keys); openssl_free_key($keys); if ($crypt === false) { require_once 'Zend/Filter/Exception.php'; throw new Zend_Filter_Exception('Openssl was not able to decrypt you content with the given options'); } // decompress after decryption if (!empty($this->_compression)) { require_once 'Zend/Filter/Decompress.php'; $decompress = new Zend_Filter_Decompress($this->_compression); $decrypted = $decompress->filter($decrypted); } return $decrypted; }
public static function factoryFromEncrypted($envKey, $encData, $privateKeyFilePath, $privateKeyPassword = null) { $privateKey = null; if ($privateKeyPassword == null) { $privateKey = @openssl_get_privatekey("file://{$privateKeyFilePath}"); } else { $privateKey = @openssl_get_privatekey("file://{$privateKeyFilePath}", $privateKeyPassword); } if ($privateKey === false) { throw new Exception('Error loading private key', self::ERROR_CONFIRM_LOAD_PRIVATE_KEY); } $srcData = base64_decode($encData); if ($srcData === false) { @openssl_free_key($privateKey); throw new Exception('Failed decoding data', self::ERROR_CONFIRM_FAILED_DECODING_DATA); } $srcEnvKey = base64_decode($envKey); if ($srcEnvKey === false) { throw new Exception('Failed decoding envelope key', self::ERROR_CONFIRM_FAILED_DECODING_ENVELOPE_KEY); } $data = null; $result = @openssl_open($srcData, $data, $srcEnvKey, $privateKey); if ($result === false) { throw new Exception('Failed decrypting data', self::ERROR_CONFIRM_FAILED_DECRYPT_DATA); } return self::factory($data); }