<div dir="ltr">Peter,<div><br></div><div>Thanks for engaging, and <span style="font-size:12.8px">walls of words with way too long sentences are all too easy to create - I'm also bad at occasionally using the wrong word (public vs private, for instance) which can render the whole wall confused.</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">So, my main challenge is that I have to "code and release" this system to a bunch of users who aren't going to be lifting a finger for security, but want security anyway. The basic topology is: many machines sold to various customers around the world, with occasional data exchanged between machines and occasional software updates sent out. (Occasional meaning: 0 or more.)</span></div><div><br></div><div>In the (less important) description of my symmetric "obscurity" code, background may help. These are files generated by machines in the field, for consumption by other machines in the field with no opportunity for key exchange. The reason I call it obscurity is because, eventually someone may discover the algorithm and key - at which point the files can be decrypted, modified, re-encrypted, etc. There's nothing of inherent value in these files, just option settings which anyone with physical access can change anyway - but, we want reasonable assurance that "hackers" won't be toying with the machines by playing with these files.</div><div><br></div><div>To achieve this "obscurity/security" machine to machine, I have embedded a key in the executable code (I know, I know, but is there a better way that does not rely on user actions?) The "salt" in the algorithm is a block of random data that becomes the first encrypted block. The settings data is then encrypted, and the hash of the salt+settings data is encrypted, hopefully achieving the goals of:</div><div><br></div><div>a) settings are not stored in plaintext to prevent "easy hacking" </div><div><br></div><div>b) identical settings files will appear different when encrypted due to the salt, even though the key and iv do not change, making one route to discovery of the key a little harder, and </div><div><br></div><div>c) if anything is changed without knowledge of the key, iv and algorithm, the hash of the decrypted settings will not match the hash traveling with the encrypted file, preventing randomly tampered files from being accepted as valid.</div><div><br></div><div>Since these machines are "released to the wild" and must occasionally communicate with each other this way, with essentially no guarantee of opportunity for updates after release, I don't see a more secure alternative?</div><div><br></div><div><br></div><div>The more important function is distribution of updates, and this is the one that I want to employ public/private key encryption since the update files are generated in a controlled location where we have the opportunity to at least attempt to keep the private key confidential. TLS would be nice, but our update files may also arrive via USB stick, aka sneakernet... All the other limitations still apply - machines are sent into the wild and may not have the opportunity for updates for years, if ever, but when we do send an update we want the machine to be as certain as possible that it is an intact authorized update. Additionally, it is desired (but not critical) for the contents of the update to be opaque to anyone who may examine the file.</div><div><br></div><div>Thanks for the refresher on practical usage of RSA - my last "under the hood" work with it was in the 1980s... Would this example be a correct usage?</div><div><br></div><div><span style="font-size:12.8px">1 - We will use an RSA keypair with modulus n, public exponent e and private </span><span style="font-size:12.8px">exponent d, public exponent pre-programmed on the machines when manufactured, private exponent held at the company.</span><br style="font-size:12.8px"><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">2 - The message we want to send securely is: "Software updater from 1.0 to 1.1" c</span><span style="font-size:12.8px">ompute a secure hash S</span><span style="font-size:12.8px">H of the message say using SHA-3-512</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">3 - Compute SHe = sk^d mod n</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">4 - Obscure the composite message </span><span style="font-size:12.8px">SHe+</span><span style="font-size:12.8px">"Software updater from 1.0 to 1.1" using a pre-shared symmetric key and algorithm (perhaps as described above)</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">5 - Recipient machine de-obscures the composite message using the pre-shared symmetric key</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">6 - Recipient machine decrypts SH = SHe^e mod n and then can be certain that the message is valid because only the factory knows d</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Unfortunately, my hands are somewhat tied with respect to key lifecycle. I might be able to update some keys on some machines, but there is always the (high likelihood) that a machine with just the original key will be out there needing an update. I'm starting to see the attraction of gpgme for managing a list of keys, and possibly invalidating older keys with new updates, but does it provide a mechanism for multiple authentications on a single message? ( Like: SHe1+SHe2...+SHeN+"Authenticated message" ? )</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Thanks,</span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Mike</span></div><div><span style="font-size:12.8px"><br></span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 11, 2018 at 10:29 AM, Peter Lebbing <span dir="ltr"><<a href="mailto:peter@digitalbrains.com" target="_blank">peter@digitalbrains.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 11/04/18 14:51, Mike Inman wrote:<br>
> Encrypt the message with a symmetric algorithm, adding salt and a<br>
> hash/checksum to ensure validity.<br>
<br>
</span>I'm not sure what you're salting exactly, but anyway, this is not the focal<br>
point of my reply. By the way, there are many ways to do what you describe in<br>
such a way that the hash is utterly pointless and not authentication. For a<br>
sweet example, check the use of CRC inside a stream cipher in WEP, the original<br>
encryption layer of wireless LANs :-). Stream cipher + CRC = major D'oh!<br>
<span class=""><br>
> When I studied cryptography at Uni in the 1980s, they taught that<br>
> private/public key encryption was a more or less interchangeable affair -<br>
> the only difference between a private key and a public key is the manner in<br>
> which they are handled.<br>
<br>
</span>This is only true for some algorithms and not for others, and even then only to<br>
some extent.<br>
<br>
For example, with RSA, encryption is: encrypt message with random key,<br>
RSA-encrypt this random key to the private key of the intended recipient.<br>
<br>
RSA signatures is the opposite, where a hash matching the signed data is<br>
RSA-"encrypted" to the public key. Only the private key can "encrypt" to the<br>
public key, so when anybody uses the public key to "decrypt" it, they can verify<br>
the hash matches and was produced by the holder of the private key.<br>
<br>
So for encryption, you choose the number and send it to the private key.<br>
<br>
In signing, you obtain the number by hashing and send it to the public key.<br>
<br>
They are mathematically equivalent. But note that the public and private key are<br>
not interchangeable. The public exponent usually has a very low Hamming weight<br>
while the private exponent is derived after fixing the public exponent. Simply<br>
exchanging public and private variables would not give an equivalent keypair,<br>
although mathematically they'd still work.<br>
<span class=""><br>
> As such, I am a little disappointed in the GnuPGP<br>
> implementation that doesn't allow encryption with the private key to serve<br>
> as authentication and obscurity of the message - our <br>
> *** not private, but public *** key will be<br>
> obscured, but obviously not secured since attackers may have control of the<br>
> standard computer system it is contained in.<br>
<br>
</span>Obscurity can be obtained by many low-complexity methods and is not a goal of<br>
OpenPGP. There is no O in PGP :-). (Oh, and the GnuPG implementation wouldn't<br>
usually add such a major deviation from the OpenPGP standard.)<br>
<br>
And how do you see this as authentication? The way you describe it, I'm thinking<br>
you simply reverse the roles of the public and private key, and you are thus<br>
encrypting the session key to the public key with your private key instead of<br>
the other way around. What does this achieve? As you'd then be sharing the<br>
symmetric encryption key with the world, anybody could re-encrypt their<br>
malicious data to that symmetric key, tag the so-called "encrypted" asymmetric<br>
algorithm output that only the private key can produce on and presto,<br>
"authenticated" data. If this is what you meant, well, I've just explained it's<br>
not authentication. If this is not what you meant, please elaborate.<br>
<br>
Okay, that was a wall of words with way too long sentences. So let me combine it<br>
with an example.<br>
<br>
1 - We will use an RSA keypair with modulus n, public exponent e and private<br>
exponent d<br>
<br>
2 - Choose symmetric key: sk = 0x2dfe0af9eeb3352c390791f4710a<wbr>63da<br>
<br>
3 - Encrypt "Transfer $ 1000 to Mike" using AES and the symmetric key sk from 2.<br>
Let's call this result "BONAFIDEDATA"<br>
<br>
4 - Compute s = sk^d mod n<br>
This is "encrypting" the symmetric key sk to the public key. It is equal to what<br>
PKCS#1 would consider the signature primitive RSASP1, mathematically equivalent<br>
to the decryption primitive RSADP.<br>
<br>
5 - Send s + "BONAFIDEDATA" to recipient<br>
<br>
6 - Recipient computes sk = s^e mod n<br>
This is "decrypting" the symmetric key sk using the public key. It is equal to<br>
what PKCS#1 would consider the verification primitive RSAVP1, mathematically<br>
equivalent to the encryption primitive RSAEP.<br>
<br>
7 - Recipient decrypts "BONAFIDEDATA" using the correct sk, yielding "Transfer $<br>
1000 to Mike".<br>
<br>
8 - Mike has spending money.<br>
<br>
Now I come along.<br>
<br>
1 - Intercept or observe on the network s + "BONAFIDEDATA". Preventing reception<br>
is optional.<br>
<br>
2 - I compute sk = s^e mod n<br>
This is public data.<br>
<br>
3 - Encrypt "Transfer $ 10,000 to Peter" using AES and sk, which we correctly<br>
determined to be 0x2dfe0af9eeb3352c390791f4710a<wbr>63da. Let's call the result<br>
"FAKEDDATA"<br>
<br>
4 - Send s + "FAKEDDATA" to recipient<br>
<br>
5 - Recipient computes sk = s^e mod n<br>
This is "decrypting" the symmetric key sk using the public key. It is equal to<br>
what PKCS#1 would consider the verification primitive RSAVP1, mathematically<br>
equivalent to the encryption primitive RSAEP.<br>
<br>
6 - Recipient decrypts "FAKEDDATA" using the correct sk, yielding "Transfer<br>
$ 10,000 to Peter".<br>
<br>
7 - Peter has spending money, and then some.<br>
<span class=""><br>
> Unless I'm missing something?<br>
<br>
</span>If you were to use OpenPGP encryption instead of a shared symmetric key, key<br>
management and access revocation becomes much simpler. Additionally, you'd be<br>
encrypting much less data with the same symmetric key. So there are some more<br>
gotcha's with a static symmetric key: don't choose a symmetric algorithm with a<br>
64-bit block size, etcetera. That's the thing about inventing your own crypto,<br>
even at such a high level. It seems much simpler to me to use a private key that<br>
is stored in plaintext on your recipient machine. Or TLS with the same, which by<br>
the way is an extremely common setup, much more so than a passphrase-less<br>
OpenPGP private key, even though they are the same principle.<br>
<br>
HTH,<br>
<br>
Peter.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
I use the GNU Privacy Guard (GnuPG) in combination with Enigmail.<br>
You can send me encrypted mail if you want some privacy.<br>
My key is available at <<a href="http://digitalbrains.com/2012/openpgp-key-peter" rel="noreferrer" target="_blank">http://digitalbrains.com/<wbr>2012/openpgp-key-peter</a>><br>
<br>
</font></span></blockquote></div><br></div>