Frequently Asked Questions
--------------------------

When will support for Python 2.7 stop?
++++++++++++++++++++++++++++++++++++++++

There are no plans to drop support for Python 2.7.
This may change when maintenance becomes too cumbersome.

However, new features will only be tested for Python 3.

How can I encrypt using an ECC key?
++++++++++++++++++++++++++++++++++++

Use Hybrid Public Key Encryption (HPKE, RFC 9180)
and the module :ref:`Crypto.Protocol.HPKE<hpke>`.

Is CTR cipher mode compatible with Java?
++++++++++++++++++++++++++++++++++++++++++++++++++

Yes. When you instantiate your AES cipher in Java::

   Cipher  cipher = Cipher.getInstance("AES/CTR/NoPadding");

   SecretKeySpec keySpec = new SecretKeySpec(new byte[16], "AES");
   IvParameterSpec ivSpec = new IvParameterSpec(new byte[16]);

   cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);

You are effectively using :ref:`ctr_mode` without a fixed nonce and with
a 128-bit big endian counter starting at 0.
The counter will wrap around only after 2¹²⁸ blocks.

You can replicate the same keystream in PyCryptodome with::

   ivSpec = b'\x00' * 16
   ctr = AES.new(keySpec, AES.MODE_CTR, initial_value=ivSpec, nonce=b'')

Are RSASSA-PSS signatures compatible with Java?
+++++++++++++++++++++++++++++++++++++++++++++++

Yes. For Java, you must consider that by default the
mask is generated by MGF1 with SHA-1 (regardless of how you hash
the message) and the salt is 20 bytes long.

If you want to use another algorithm or another salt length,
you must instantiate a ``PSSParameterSpec`` object, for instance::

   Signature ss = Signature.getInstance("SHA256withRSA/PSS");
   AlgorithmParameters pss1 = ss.getParameters();
   PSSParameterSpec pssParameterSpec = new PSSParameterSpec("SHA-256", "MGF1", new MGF1ParameterSpec("SHA-256"), 32, 0xBC);
   ss.setParameter(spec1);

Are RSASSA-PSS signatures compatible with OpenSSL?
++++++++++++++++++++++++++++++++++++++++++++++++++

Yes, but one quirk of OpenSSL (and of a few other libraries,
especially if they are wrappers to OpenSSL) is that the salt
length is computed in two possible ways:

.. list-table::

   * - **Salt length**
     - **Value for** ``EVP_PKEY_CTX_set_rsa_pss_saltlen()``
     - ``openssl pkeyutl`` **command**
   * - Same as digest size
     - ``RSA_PSS_SALTLEN_DIGEST``
     - ``-pkeyopt rsa_pss_saltlen:digest``
   * - Maximized
     - ``RSA_PSS_SALTLEN_MAX``
     - ``-pkeyopt rsa_pss_saltlen:max``

In PyCryptodome, the salt length matches the digest size by default
(which is what `RFC8017 <https://tools.ietf.org/html/rfc8017#page-40>`_ recommends).
However, you can also maximize the salt length with::

   key = RSA.import_key(open('privkey.der').read())
   h = SHA256.new(message)
   max_salt_bytes = key.size_in_bytes() - h.digest_size - 2
   signature = pss.new(key, salt_bytes=max_salt_bytes).sign(h)

Why do I get the error ``No module named Crypto`` on Windows?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Check the directory where Python packages are installed, like::

        /path/to/python/Lib/site-packages/

You might find a directory named ``crypto``, with all the PyCryptodome files in it.

The most likely cause is described `here <https://github.com/dlitz/pycrypto/issues/156>`_ and you can fix the problem with::

        pip uninstall crypto
        pip uninstall pycryptodome
        pip install pycryptodome

The root cause is that, in the past, you most likely have installed an unrelated but similarly named package called `crypto <https://pypi.org/project/crypto/>`_,
which happens to operate under the namespace ``crypto``.

The Windows filesystem is **case-insensitive** so ``crypto`` and ``Crypto`` are effectively considered the same thing.
When you subsequently install ``pycryptodome``, ``pip`` finds that a directory named with the target namespace already exists (under the rules of the underlying filesystem),
and therefore installs all the sub-packages of ``pycryptodome`` in it.
This is probably a reasonable behavior, if it wasn't that `pip does not issue any warning even if it could detect the issue <https://github.com/pypa/pip/issues/3309>`_.

Why does ``strxor`` raise ``TypeError: argument 2 must be bytes, not bytearray``?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Most probably you have installed both the ``pycryptodome`` and the old ``pycrypto`` packages.

Run ``pip uninstall pycrypto`` and try again.

The old PyCrypto shipped with a ``strxor`` module written as a native library (``.so`` or ``.dll`` file).
If you install ``pycryptodome``, the old native module will still take priority over the new Python extension that comes in the latter.

Why do I get a ``translation_unit_or_empty undefined`` error with ``pycparser``?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Unfortunately,``pycparser`` does not work with optimzed (``-O``) Python builds,
which strips out the docstrings, causing this error.
This is a `known issue <https://github.com/eliben/pycparser/issues/291>`_ and it will not be fixed.

The possible workarounds are:

* Do not run Python iwth ``-O``
* Remove `cffi` and ``cparser``. PyCryptodome will fall back to ``ctypes`` for interfacing with the native modules.
* Use an earlier version of ``cparser`` (2.14)
