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

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 or OpenSSL?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

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);

On the other hand, a quirk of OpenSSL (and of a few other libraries,
especially if they are wrappers to OpenSSL)
is that the default salt length is maximized, and it does not match in size the digest applied to the message,
as recommended in `RFC8017 <https://tools.ietf.org/html/rfc8017#page-40>`_.
In PyCryptodome, you maximize the salt length with::

   key = RSA.import_key(open('privkey.der').read())
   h = SHA256.new(message)
   salt_bytes = key.size_in_bytes() - h.digest_size - 2
   signature = pss.new(key, salt_bytes=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.
