[Cryptography-dev] Thoughts on opaque key material.
David Reid
dreid at dreid.org
Tue Apr 22 01:15:20 CEST 2014
I apologize for how disorganized these thoughts are, the problems are more
fully formed than
the solutions and I ended up spending much more time than desired writing
this email, so I just sort of cut myself off at 4pm. Hopefully we can
figure out some of these answers on the mailing list.
--
Currently RSA key material is represented as an object having a series of
properties that correspond to the various mathematical components of an
RSA key.
The initial reasoning for this is that it would make the internal
representation of a key backend independent and allow for moving key
material from one backend to another (for example, loading the key from one
backend and performing encryption with another backend).
However, as an initial proponent of this argument I feel comfortable saying
that I was completely wrong. It has variety of negative effects,
1) The mathematical components have terrible names that we MUST expose to
users. In RSA n, p, q, e, and d. In ECDSA x and y.
Even when these components have well known multisyllable names their
value
as descriptors is somewhat limited, "public exponent" is a much better
name
than "e" but still requires knowledge of the mathematical foundations of
RSA to be of any value to anyone. (You can argue that the
hazmat/primitives layers are the place for exposing this kind of detail
to
users and that if you don't understand the RSA mathematically you
shouldn't
be using them, however we've never felt any need to point out that AES
S-boxes can be described by a system of 23 quadratic equations in 80
terms.)
2) Not all backend representations of keys expose the individual components.
Even given a single backend such as openssl there is no guarantee that
two internal structures will contain all the necessary data. This is
most notable with keys stored in a HSMs or SmartCards where it is a
feature
that you can not extract the RSA private key from the system.
However this is also evident in backends like CommonCrypto which don't
have
a public API for getting or setting the values of the various key
components. To actually use an RSA key from OpenSSL on CommonCrypto you
MUST convert it to some intermediate representation that both understand
(likely PKCS#8).
3) Optional optimizations get exposed to users as required interface.
Similarly, our exposure of the Chinese remainder theorem intermediate
calculations on the RSAPrivateKey interface complicates the usage of RSA
key material on multiple backends instead of simplifies it. Not all
serialization formats or backends support storing/loading the CRT values
potentially requiring us to perform duplicate calculations of these
values
for exposing them on the nonopaque interface.
4) Using the generic key components makes frequent operations (like
obtaining
a new signing/verify context) more expensive.
These backend specific operations now require potentially costly (or even
dangerous) conversions between the generic and backend
specific representations.
Given these issues I think we must seriously consider switching away from
these backend independent representations as our primary interface to key
materials. Preferring instead opaque backend specific implementations.
For example, instead of a concrete RSAPrivateKey instance which can be
instantiated with the underlying components, I imagine all key generation
and
loading being mediated by backends and resulting in objects that provide
much
more narrow interfaces organized around what you can do with a key (instead
of
what a key intrinsically is). For example, when generating an RSA key on
the
openssl backend you would get back an object which provides a basic
interface
indicating that it is an RSA key, that has some basic attributes for key
size, and accessing the public key object, then methods for obtaining
backend
specific contexts for performing signing/verification and
encryption/decryption operations.
In addition to those basic operations the object may provide any number of
backend specific serialization methods, potentially including "serializing"
the
key to something similar to the current interface (which we can think of as
a
bag of bignums).
In this way we can facilitate converting between backend specific key
representations through a process of serialization/deserialization (in many
cases through a formal specification such as PKCS#8).
-David
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cryptography-dev/attachments/20140421/3687fbf9/attachment-0001.html>
More information about the Cryptography-dev
mailing list