Goodbye, PKI!

I did my Friday lecture on PKI (Public Key Infrastructure) and digital certificates, and outlined how poor our core security is on the…

Goodbye, PKI!

I did my Friday lecture on PKI (Public Key Infrastructure) and digital certificates, and outlined how poor our core security is on the Internet. It is a terrible hot-potch of things that few people — even security professionals — actually understand. It was created at a time when the Internet was a good deal smaller, and created a structured model of root CAs (Certificate Authorities) and intermediary CAs. But it also supported self-signed certificates. If you are interested, here’s the content from the class [https://asecuritysite.com/esecurity/unit06].

Gather a whole lot of information security professionals, and they will often struggle to explain how the whole thing works. In the end, it’s a bit like gathering a whole lot of electrical engineers, and asking them how Ohm’s Law works, and then getting a garbled response. Would you trust an electrical engineer how couldn’t tell you exactly how current and voltage work?

Developers, too, often fail into traps of not properly signing their code and will leave the private key exposed to others. Certificates time-out. Simple passwords are used on the core certificates. Adversaries target the installation of root CA certificates, in order that their malicious software will be trusted. And so on …

So the story goes. You send me a secure email, and you take a hash of the email content, and then encrypt this with your private key. This creates the signature for the message. You create a new AES key, and take the message and the signature and then encrypt the whole lot. Next you take my public key and encrypt the AES key, and send me the whole lot. On the other other side you decrypt the symmetric key with your private key, and then can read the message. You decrypt the hash with my public key, and then check against the hash of the message. If all checks out, you have validated that the message was sent by me, and hasn’t change, and that no-one else will have read the email. But! Wait! A problem! How can we trust the public keys that are being passed. Well, that’s where PKI comes in, and where we create a trust infrastructure of signers. At the top, there are root CAs, and which can verify any public key. And so the power of the Internet is in the hands of a few root signers, and those who creep into your trusted root store, and … well .. anyone.

But there is another way. The world of cryptography has moved on since the 1980s, and we now have newer ways of distributing our public key and in signing for transactions. There is no more checking of digital certificates, as the power is in the hands of those who create the key pairs.

For Blockchain, we didn’t have the legacy of PKI, and the solution is just to create a key pair — without requiring a trusted CA to validate it — and then this can be used to create an identity. Everything on the Internet, too, can be seen as just a whole lot of transactions … sending a email, reading an email, and so on. If we view the transaction, we have a sender and a recipient, and then some content. Then private key is used to sign for a transaction, and to validate the sender and its contents. It’s as simple as that.

With Blockchain, the genius is that we don’t need a digital certificate anymore, we can create a signature which embeds our public key. In this way the signature can be checked without requiring the distribution of the public key. And say goodnight to PKI!

With blockchain we create an identity, with a randomly generated private key. From this we can then derive a public key, and then an address. The address, private key, and public key, will be unique across the whole of the Internet:

We can then create a hash of a message with Keccak. Next we can sign a message with the private key, and then extract the address from the signature. A sample run is [here]:

Message:	 hello
-----Identity-------
{ address: '0x6E4a8C00FDcD579b504130568d730BAf70874055',
privateKey: '0x6066fa7e881b24dc112653cfc5d9774cb42ded274d91de9921d4b0eb285c06e0',
publicKey: '7ddd87f067882e0744c669c0bb8563831f26266f6519674bbc8d2ba94d9751bfb918de24d718c7f0bd4fc6b70a810f16363c915dea7867ba04a348404eadea07' }
-----Message Hash (Keccak)-------
0x1c8aff950685c2ed4bc3174f3472287b56d9517b9c948127319a09a7a36deac8
------Signature of message----
0x70d3636fb7007bd0d6b6d7d9b1face5214c2e6591814629e1d2bb341062b4e5b095d40cc5e041f54e70a01721ad34fc44329f6b653833c3ce049eff68281297d1b
------Extracting Signer from signature------
0xd720D74A9C2b4BeF49E8b32a2a4322d182609156
----Transaction-------
f86c8085012a05f200825208943fd91467c1dc509ff146c617872f706771cfb80b880de0b6b3a7640000801ba03dd88753d272e892c030fae6eb8847fd1077bbd5142c2bf58dece87f376a2f84a032ffa03f32f79cdc86d1270dc5edd961a7a560f74d7b392704ab81bc01a8abaf

In this case our Ethereum transaction is:

f86c8085012a05f200825208943fd91467c1dc509ff146c617872f706771cfb80b880de0b6b3a7640000801ba03dd88753d272e892c030fae6eb8847fd1077bbd5142c2bf58dece87f376a2f84a032ffa03f32f79cdc86d1270dc5edd961a7a560f74d7b392704ab81bc01a8abaf

and will contain the message of the transaction, the sender, the receiver, and a provable version of the identity of the sender, and that they have signed the message. The following is some sample code and uses the eth-crypto module (and which is installed with ‘npm eth-crypto’). In this case the current user is sending a signed message to ‘0x3fD91467C1d..71cFB80b’, and where we take the message hash and serialize it:

const EthCrypto = require('eth-crypto');
const args = process.argv.slice(3);
const message= args[0];
console.log("Message:\t",message);
const identity = EthCrypto.createIdentity();
console.log("\n-----Identity-------\n",identity);
const messageHash = EthCrypto.hash.keccak256(message);
console.log("\n-----Message Hash (Keccak)-------\n",messageHash);
const signature = EthCrypto.sign(
identity.privateKey, // privateKey
messageHash // hash of message
);
console.log("\n------Signature of message----\n",signature);
const signer = EthCrypto.recover(
signature,
EthCrypto.hash.keccak256('foobar') // signed message hash
);
console.log("\n------Extracting Signer from signature------\n",signer);
const rawTransaction = {
from: identity.address,
to: '0x3fD91467C1dc509Ff146c617872f706771cFB80b',
value: 1000000000000000000,
nonce: 0,
gasPrice: 5000000000,
gasLimit: 21000
};
const serializedTx = EthCrypto.signTransaction(
rawTransaction,
identity.privateKey
);
console.log("\n----Transaction-------\n",serializedTx);

And so, did you see what we did there? I can now create my own ID — with my key pair — and then send you a signed message. You just basically read the message, and it will reveal my identity, and which relates to my private key — and which I only own.

This model allows us to create our own trusted ID, and to sign for things. Dave the Developer can now apply his public key onto the blockchain, and then sign things into GitHub using his trusted signature:

No smoke and mirrors — No complex setups with certificate stores, that few people actually understand — No trusted root CAs — No time-outs of certificates — No certificate signing requests — Just a citizen-focused model of how the Internet should have been built. Say goodbye to the 20th Century, and to a new model of our more trusted world.