This all started because the EU decided that one can't use cookies without authorisation, so how to hand state around a website without client side storage.
I investigated some things and played with SSL.
It works like this :
plain -> encryption with public key -> cipher
cipher -> decryption with private key -> plain
or
plain -> encryption with private key -> cipher
cipher -> decryption with public key -> plain
Using this mechanism one can envisage a system where two entities can communicate by first exchanging public keys and then encrypted data that only the recipient can decrypt.
First off we're going to need some keys. These are generated using the openssl command line tools.
% openssl genrsa -out private.pem 1024
% openssl rsa -in private.pem -out public.pem -outform PEM -pubout
If you're feeling fruity you can keep them both in the same file, remembering not to send it when you mean to just send the public part !
% cat private.pem public.pem | tee sslkeys.pem
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDnv6zntTRDw9r0O2wJWrzyfyeVO/++9JaXAq6M60uKKNGK/Lhe
j4rrMYyN4l8arUBWJBHLaAn9VPHymXA9VdoXaPIGu+YS9fhraKUkz3eXcQhxgPXx
xAkyzOMsyEbLt7E9rQ9r9cNZVJ7rQBwloY0WHjYsZGBoT2fZI8wzz1+jTwIDAQAB
AoGAVnoAxCmqygqgfnhZ9Rel3/swwxAze4b7VnhKuAzpEDHxFyL8jVSU6vR/VUZ+
ZI73re0hsrws1hpHelZlOo35pgLZif230IgpNfZwYnvil4nTSa9oFXAr11ta/T0g
NJwxc7HovZhtwWn9vE5abRMPiZ2HAXzL5gBXjT7DsaHuNVECQQD2Tftl08GdxtVh
RNNEkHmoLHyXvfR8HLP7veGK9nGrZRhWVAqGEeKTiSw7YbMFr3Yss99o7m1fMlnP
Y9e3jsxJAkEA8N8Da2hlK+p2uNnAIukslRB4Z8VyqIWA7fNYB8u2PMO8Xsxi27NU
MNzmk69Yz2JCpmn+TiPY/3SSmS81qw2C1wJBAMA2SyJEBqziJlMqKtUvCkG7td+V
Vd4laC/lFsYjXMGsuzljjHLkMjWArwwISnT9YPOxy39P0fqgiIXYHNgakEECP0Hc
uRKleQSJF+1znRXurEIWPtYhJzjtSFPINknraekznE5PlLh+UIcL4ACB8cbDF3Zp
hR/YrX0sYul//yzGhQJAaFvthOCajq0el+aa4xMCsrtNnvFSSXSLDbAZsK0HPcpF
mVUe3tRX0dsTZ0ant35PMAEYMQhgxB9s9G+/Un/c/g==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDnv6zntTRDw9r0O2wJWrzyfyeV
O/++9JaXAq6M60uKKNGK/Lhej4rrMYyN4l8arUBWJBHLaAn9VPHymXA9VdoXaPIG
u+YS9fhraKUkz3eXcQhxgPXxxAkyzOMsyEbLt7E9rQ9r9cNZVJ7rQBwloY0WHjYs
ZGBoT2fZI8wzz1+jTwIDAQAB
-----END PUBLIC KEY-----
OBVIOUSLY don't use it for anything sensitive !
You can generate pem files that are passworded too, probably a good idea, when I find out how to do it, I'll post an update.
The code below would then use openssl_get_privatekey($pem, $passphrase);
On to the PHP bit
All very simple really :
<?php
function private_encrypt($pem, $plain) {
openssl_get_privatekey($pem);
openssl_private_encrypt($plain, $cipher, $pem);
return $cipher;
}
function private_decrypt($pem, $cipher) {
openssl_get_privatekey($pem);
openssl_private_decrypt($cipher, $plain, $pem);
return $plain;
}
function public_encrypt($pem, $plain) {
openssl_get_publickey($pem);
openssl_public_encrypt($plain, $cipher, $pem);
return $cipher;
}
function public_decrypt($pem, $cipher) {
openssl_get_publickey($pem);
openssl_public_decrypt($cipher, $plain, $pem);
return $plain;
}
?>
You can use either the combined sslkeys.pem or the appropriate public.pem / private.pem files for $pem
Do not keep the private part or combined file in your webspace
$cipher is binary so if you want to send it over text channels you will need to base64_encode it or something
e.g.
<?php
function encode($plain) {
static $pem;
if(!$pem)
$pem = file_get_contents("/etc/ssl/sslkeys.pem");
return base64_encode(public_encrypt($pem, $plain));
}
function decode($cipher) {
static $pem;
if(!$pem)
$pem = file_get_contents("/etc/ssl/sslkeys.pem");
return private_decrypt($pem, base64_decode($cipher));
}
?>
the static keyword means that the value of the variable is preserved between function calls
What to use it for
Well as it happens, I'm using it to talk to Paypal. You can sent a custom string from your Buy button and this will be sent back to you later. So I'm sending the buyer an encrypted transaction code, they send it to Paypal and then I get it back from Paypal. Like many things in the world of encryption it's easy to be fooled into thinking things are more secure than they are. But hey, at least no-one knows what I'm sending :)
Another thing that can be done is if I encrypt something with my private key, you can decrypt with my public key. By doing this you know only I (or someone who has stolen my private key :) has sent the message. If I encrypt it with your private key first then no-one else can read it except you.
I could even base64 it, upload it to pastebin, and post the URL - like so http://pastebin.com/kSnWgzHs
Then linking you and I together is much, much harder.
RIPA can lick my balls.
No comments:
Post a Comment