3

I own 2 websites, example.com and domain.com. I want to securely transfer data from example.com to domain.com. I was looking at this question which is trying to answer my main question of how to send data securely from one website to another. However, the answer's are very old.

I am wondering how I can send do this. I have the below code which basically has the encryption keys saved locally on both websites and encrypts/decrypts data based on that. However, if someone managed to guess the key, they can decrypt all the messages. Is the way I have stated below a secure method to transfer data? Or is there a better way?

function encrypt($key, $data) {
    $encryption_key = base64_decode( $key );
    if ($encryption_key === FALSE) {
        return FALSE;
    }

    $iv = openssl_cipher_iv_length('aes-256-cbc');
    if ($iv === FALSE) {
        return FALSE;
    }

    $iv = openssl_random_pseudo_bytes($iv);
    if ($iv === FALSE) {
        return FALSE;
    }

    $encrypted = openssl_encrypt($data, 'aes-256-cbc', $encryption_key, 0, $iv);
    if ($encrypted === FALSE) {
        return FALSE;
    }

    return base64_encode($encrypted . '::' . $iv);
}

function decrypt($key, $data) {

    $encryption_key = base64_decode( $key );
    if ($encryption_key === FALSE) {
        return FALSE;
    }

    $decoded_data = base64_decode($data);
    if ($decoded_data === FALSE) {
        return FALSE;
    }

    list($encrypted_data, $iv) = array_pad(explode('::', $decoded_data, 2),2,null);

    $decryption = openssl_decrypt($encrypted_data, 'aes-256-cbc', $encryption_key, 0, $iv);
    if ($decryption === FALSE) {
        return FALSE;
    }

    return $decryption;
}

So this is what would be used, and I would send the encrypted data via POST request using cURL to domain.com

// On example.com (aka sending data)
$example_key = 'key_is_123';
$data = "My secret is that I like apples";
$encrypted_msg = encrypt($example_key, $data);

echo("Sending encrypted message:\n$encrypted_msg\n\n");

// Send $encrypted_msg message via a POST request using cURL to domain.com

// On domain.com (aka receiving data)
$domain_key = $example_key;
$decrypted_msg = decrypt($domain_key, $encrypted_msg);

echo("Recieved messaged and decrypted message:\n$decrypted_msg");
Kiwa
  • 215
  • 2
  • 10
  • 1
    _"However, if someone managed to guess the key, they can decrypt all the messages."_ - well then use a key that is "unguessable" enough. What else did you think could be done ...? – CBroe Jul 01 '22 at 10:02
  • Yep, so I understand using a lengthy, random string for the key, but is the above a good way to do a data transfer? Is the encryption method secure or is there anything I can do differently or a better way to transfer data – Kiwa Jul 01 '22 at 10:05
  • The first question would be, whether you actually need any additional encryption, besides simply sending this via HTTPS. That is widely acknowledged to be sufficient enough to protect any data exchanged between me as a user, and a web server, from "prying eyes" on the way - so why would it not also be enough to exchange data between two servers in your scenario here. – CBroe Jul 01 '22 at 10:09
  • @CBroe So you are saying sending via HTTPS is basically enough encryption? Which is basically just enabling the SSL part of cURL as my websites are both HTTPS websites – Kiwa Jul 01 '22 at 10:19
  • Yes, that should be enough for standard use cases. Just make sure you don't _disable_ verification of the certificate in the cURL options. – CBroe Jul 01 '22 at 10:22
  • @CBroe Any good tutorials or examples for cURL SSL. I have Cloudflare which makes my website have HTTPS. I have never actually used cURL with SSL – Kiwa Jul 01 '22 at 10:28
  • 1
    You "use" it by simply specifying an HTTPS URL. – CBroe Jul 01 '22 at 10:31
  • `HTTPS is basically enough encryption?`... well"enough" depends on your scenario and the nature of the data you're transmitting, and any rules put in place by the owners of the data or regulations which might apply to data of that nature. e.g. I'm sure the military or secret service might have higher specifications! Or even banks and other financial institutions might insist on encrypting the files before, after and during transit _and_ having the transport encryption (i.e. HTTPS or SSL) during transmission as well. So it totally depends on the perceived risk level, as to whether it's enough. – ADyson Jul 01 '22 at 10:41
  • 1
    @Constantin I didn't fully understand what you mean – Kiwa Jul 01 '22 at 11:04
  • @ADyson But what is the industry standard way of transferring data from one website to another? The data is definitely not that sensitive, but I would still like to keep up with standards, – Kiwa Jul 01 '22 at 11:05
  • There isn't an "industry standard" - that's exactly my point. The standards are different depending on the scenario and what's been specified. However, if you have no other specific requirements, and you're transferring via HTTP then HTTPS is an obvious, easy and reliable way to encrypt the connection so that anything within it will be unreadable to someone trying to intercept the communications. – ADyson Jul 01 '22 at 11:07
  • 1
    @Constantin nobody said anything about FTP... – ADyson Jul 01 '22 at 11:12
  • @ADyson Is there any tutorial on encryption via the SSL. So I know cURL has the SSL flag you set. However, once I send off the data, how does the receiving website decrypt the SSL encryption. – Kiwa Jul 01 '22 at 11:17
  • 1
    @Constantin there's no need to get personal. But I really don't know what you're talking about and neither does Kiwa...try to make it clearer what you mean please. Are you saying that someone could compromise either of the servers? Well yes of course that's always true but it's not really relevant. We're talking about encrypting the data while it's being transmitted. If someone can steal the encryption information from the server then of course there is a big problem, but you would also have even bigger problems at the same time too. So let's assume the server is otherwise secure, for now. – ADyson Jul 01 '22 at 11:19
  • @Kiwa The webserver will handle the decryption...it's transparent to you as the developer, just like any other HTTP connection - if someone submits a form on your HTTPS website, you don't have to decrypt the form fields in the PHP code, do you? Remember with HTTPS it's the whole connection which is encrypted, so when the data hits the endpoint, the webserver automatically decrypts the whole request and passes it on to the PHP code. – ADyson Jul 01 '22 at 11:21
  • To use an analogy, HTTPS is like sending items down a tunnel - if you make the tunnel secure enough, then you don't need to secure the items within it. At the end of the tunnel they come out exactly the same as they went in, but while they're in the tunnel nobody can reach them. Whereas if you don't have the tunnel secure, then you need to put each separate item in a secure box so that if anyone breaks into the tunnel they still can't steal the items. Sometimes, if you're particularly worried about the data, you might do both at once. – ADyson Jul 01 '22 at 11:23
  • And I think that Constantin is trying to say that if someone has already broken into the rooms at either end of the tunnel (i.e. your servers) then it's pointless to have the secure tunnel or boxes. So of course you have to pay attention to the security of your servers, but hopefully would you do that anyway, and I don't think it's particularly relevant to your question. – ADyson Jul 01 '22 at 11:24
  • @ADyson So both my site's DNS's are hosted with cloudflare. Cloudflare is the the thing that converts my websites from `http://example.com` to `https://example.com` by using Full SSL mode. I've been looking at cURL SSL tutorials and I am having a bit of trouble understanding how I can turn on SSL on cURL and make it work. Do you happen to know how or happen to know of a tutorial? I see tutorials which are telling me I need the path to my SSL cert, but my SSL is provided by cloudflare (aka my DNS host) – Kiwa Jul 01 '22 at 11:36
  • That just means that the machine running the cURL code needs the relevant client-side certificate installed, to match the one on the server. That way the cURL code can trust the SSL certificate presented to it by the (Cloudflare) server when it tries to make the HTTPS request, and therefore knows it's a secure connection and not someone trying to spoof the server or run a man-in-the-middle attack. You machine might have this root certificate installed already, or it might need a bit of config. Best thing to do would be to try it initially and see if you get any errors back from cURL. – ADyson Jul 01 '22 at 11:46
  • If you want to know more about the workings of HTTPs then actually Cloudflare themselves have quite an informative article here - https://www.cloudflare.com/en-gb/learning/ssl/what-is-https, plus the page linked from it about TLS. And this one is perhaps even easier to understand actually: https://robertheaton.com/2014/03/27/how-does-https-actually-work/ . Section 3.1 of that last link is particularly relevant to what you've just asked about certificates (but read the earlier sections first, so you can understand the context too). – ADyson Jul 01 '22 at 11:50

0 Answers0