[pycrypto] PKCS#1 v1.5 and PSS

Legrandin gooksankoo at hoiptorrow.mailexpire.com
Tue Feb 8 04:43:52 CST 2011


Hi all,

I have just finalized support for PKCS#1-style RSA signatures, meaning
both v1.5 and the new PSS. I ended up spending most of the time on the
test suite, so I believe the result is pretty rock solid. I have it
shelved on a branch of my github repo, which can be retrieved via:

git clone -b pkcs1 https://github.com/Legrandin/pycrypto.git

Any feedback is appreciated!

One thing you may notice, is that Crypto.PublicKey is not touched at
all (apart from a few bugfixes and small improvements).
Instead, I have tried to isolate everything in two new modules:
Crypto.Signature.PKCS1_v1_5 and Crypto.Signature.PKCS1_PSS .

At the sender, one would do:

>>> from Crypto.Signature import PKCS1_v1_5
>>> from Crypto.Hash import SHA
>>> from Crypto.PublicKey import RSA
>>>
>>> message = 'To be signed'
>>> key = RSA.importKey('key.der')
>>> h = SHA.new()
>>> h.update(message)
>>>> signature = PKCS1_v1_5.sign(h, key)

whereas at the receiver:

>>> key = RSA.importKey('pubkey.der')
>>> h = SHA.new()
>>> h.update(message)
>>> if PKCS_v1_5.verify(h, key, signature):
>>> print "The signature is authentic."
>>>     else:
>>> print "The signature is not authentic."

Note that no object is used in such modules, because the signing
algorithms are inherently stateless.

I believe this way is much cleaner that expanding the already shaky RSA.sign() !

More generally, using a Crypto.PublicKey.RSA object as both key (e.g.
generation) and key engine (signing, encryption) seems to be the root
of a lot of troubles. It would be much better to use such object (and
the same applies to everything under Crypto.PublicKey) only for key
management, and leave all usages of such key to a different module.

That is the same approach found in the Java Crypto Architecture (see
http://download.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html)
which applies the concept to all key types, including symmetric ones.
In PyCrypto, the fact that Cipher.AES is used to model both the key
and the raw algorithm seem to be still acceptable though, because key
management for AES does not require a lot of logic like for public
keys.

For such reasons, while thinking how to implement the PKCS#1 OAEP algo
I need, I was considering how the Crypto.Cipher package could be a
good candidate for holding a new PKCS1_OAEP module. Mixing up
symmetric key objects and an asymmetric algo may seem bad at first,
but JCA indeed has a Cipher class meant to cover all encryption algos,
no matter the type. On the long run, we may actually want to move
symmetric keys into a Crypto.SymmetricKey module, and leave
Crypto.Cipher for key usage only, and no key management.


More information about the pycrypto mailing list