Port from PyCrypto to PyCroptodome

As the PyCrypto website says [1]:

> PyCrypto 2.x is unmaintained, obsolete, and contains security
> vulnerabilities.

Therefore, switch to PyCryptodome, a maintained PyCrypto fork
which is listed there as the recommended alternative for
existing software that depends on PyCrypto.

Notes on the port:

1) As the PyCryptodome introduction documentation [2] says,
there are 2 alternative projects/namespaces that can be
used:

* pycryptodome, which uses the `Crypto` package
  that PyCrypto also uses, so is almost a drop-in
  replacement for Pycrypto

* pycryptodomex, which uses the `Cryptodome` package

It also mentions that the use of pycryptodome
"is therefore recommended only when you are
sure that the whole application is deployed in a virtualenv".

Since it isn't sure that the application is deployed in a
virtualenv, to make it more explicit that PyCryptodome
is being used and because Linux distros like Debian
package the `Cryptodome` package [3], the port is done to
the `pycryptodomex` library that uses the `Cryptodome`
package name.

2) As the "Compatibility with PyCrypto" page in the PyCryptodome
doc [4] says:

> The following packages, modules and functions have been removed:
>
> * Crypto.Random.OSRNG, Crypto.Util.winrandom and Crypto.Random.randpool.
>   You should use Crypto.Random only.

The `PublicKey.RSA.generate` method already uses
`Crypto.Random.get_random_bytes()` as default [5],
so just drop the second parameter using `RandomPool.getBytes`
in `virtualsmartcard/src/vpicc/virtualsmartcard/cards/cryptoflex.py`.

[1] https://www.pycrypto.org/
[2] https://www.pycryptodome.org/src/introduction
[3] https://packages.debian.org/bullseye/python3-pycryptodome
[4] https://pycryptodome.readthedocs.io/en/latest/src/vs_pycrypto.html
[5] https://pycryptodome.readthedocs.io/en/latest/src/public_key/rsa.html
This commit is contained in:
Michael Weghorn
2022-09-17 21:55:40 +02:00
parent 141509cce3
commit 22edc2a228
6 changed files with 16 additions and 18 deletions

View File

@@ -103,7 +103,7 @@ Depending on your usage of the |vpicc| you may need to install the following:
- Python_
- pyscard_ (relaying a local smart card with `--type=relay`)
- PyCrypto_, PBKDF2_, PIL_, readline_ or PyReadline_ (emulation of electronic
- PyCryptodome, PBKDF2_, PIL_, readline_ or PyReadline_ (emulation of electronic
passport with `--type=ePass`)
- OpenPACE_ (emulation of German identity card with `--type=nPA`)
- libqrencode_ (to print a QR code on the command line for `vpcd-config`; an
@@ -320,7 +320,7 @@ requiremets are installed as follows::
sudo apt-get install python2.7-dev
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
python2.7 get-pip.py
python2.7 -m pip install pycrypto pyscard
python2.7 -m pip install pycryptodomex pyscard
python2.7 readpass.py --no-gui
git clone https://github.com/henryk/cyberflex-shell
cd cyberflex-shell
@@ -354,7 +354,7 @@ Notes and References
.. _PCSC-lite: https://pcsclite.apdu.fr/
.. _Python: http://www.python.org/
.. _pyscard: http://pyscard.sourceforge.net/
.. _PyCrypto: http://pycrypto.org/
.. _PyCryptodome: https://www.pycryptodome.org/
.. _PBKDF2: https://www.dlitz.net/software/python-pbkdf2/
.. _readline: https://docs.python.org/3.3/library/readline.html
.. _PyReadline: https://pypi.python.org/pypi/pyreadline

View File

@@ -25,12 +25,12 @@ from random import randint
from virtualsmartcard.utils import inttostring
try:
# Use PyCrypto (if available)
from Crypto.Cipher import DES3, DES, AES, ARC4 # @UnusedImport
from Crypto.Hash import HMAC
# Use PyCryptodome (if available)
from Cryptodome.Cipher import DES3, DES, AES, ARC4 # @UnusedImport
from Cryptodome.Hash import HMAC
except ImportError:
# PyCrypto not available. Use the Python standard library.
# PyCryptodome not available. Use the Python standard library.
import hmac as HMAC
CYBERFLEX_IV = b'\x00' * 8
@@ -83,7 +83,7 @@ def get_cipher_keylen(cipherspec):
# cipher = globals().get(cipherparts[0].upper(), None)
# Note: return cipher.key_size does not work on Ubuntu, because e.g.
# AES.key_size == 0
if cipher == "AES": # Pycrypto uses AES128
if cipher == "AES": # PyCryptodome uses AES128
return 16
elif cipher == "DES":
return 8

View File

@@ -98,8 +98,7 @@ class CryptoflexSE(Security_Environment):
Used to specify the key length. The mapping is: 0x40 => 256 Bit,
0x60 => 512 Bit, 0x80 => 1024
"""
from Crypto.PublicKey import RSA
from Crypto.Util.randpool import RandomPool
from Cryptodome.PublicKey import RSA
keynumber = p1 # TODO: Check if key exists
@@ -110,8 +109,7 @@ class CryptoflexSE(Security_Environment):
else:
keylength = keylength_dict[p2]
rnd = RandomPool()
PublicKey = RSA.generate(keylength, rnd.get_bytes)
PublicKey = RSA.generate(keylength)
self.dst.key = PublicKey
e_in = struct.unpack("<i", data)