mirror of
https://github.com/Legrandin/pycryptodome.git
synced 2025-12-08 05:19:46 +00:00
Added remaining ciphers to API
This commit is contained in:
parent
dbc7c7bb3d
commit
c24d223929
10 changed files with 402 additions and 414 deletions
35
Doc/src/cipher/arc2.rst
Normal file
35
Doc/src/cipher/arc2.rst
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
RC2
|
||||||
|
===
|
||||||
|
|
||||||
|
RC2_ (Rivest's Cipher version 2) is a symmetric block cipher designed
|
||||||
|
by Ron Rivest in 1987. The cipher started as a proprietary design,
|
||||||
|
that was reverse engineered and anonymously posted on Usenet in 1996.
|
||||||
|
For this reason, the algorithm was first called *Alleged* RC2 (ARC2),
|
||||||
|
since the company that owned RC2 (RSA Data Inc.) did not confirm whether
|
||||||
|
the details leaked into public domain were really correct.
|
||||||
|
|
||||||
|
The company eventually published its full specification in RFC2268_.
|
||||||
|
|
||||||
|
RC2 has a fixed data block size of 8 bytes. Length of its keys can vary from
|
||||||
|
8 to 128 bits. One particular property of RC2 is that the actual
|
||||||
|
cryptographic strength of the key (*effective key length*) can be reduced
|
||||||
|
via a parameter.
|
||||||
|
|
||||||
|
Even though RC2 is not cryptographically broken, it has not been analyzed as
|
||||||
|
thoroughly as AES, which is also faster than RC2.
|
||||||
|
|
||||||
|
**Use AES, not ARC2. This module is only provided for legacy purposes.**
|
||||||
|
|
||||||
|
As an example, encryption can be done as follows::
|
||||||
|
|
||||||
|
>>> from Crypto.Cipher import ARC2
|
||||||
|
>>>
|
||||||
|
>>> key = b'Sixteen byte key'
|
||||||
|
>>> cipher = ARC2.new(key, ARC2.MODE_CFB)
|
||||||
|
>>> msg = cipher.iv + cipher.encrypt(b'Attack at dawn')
|
||||||
|
|
||||||
|
.. _RC2: http://en.wikipedia.org/wiki/RC2
|
||||||
|
.. _RFC2268: http://tools.ietf.org/html/rfc2268
|
||||||
|
|
||||||
|
.. automodule:: Crypto.Cipher.ARC2
|
||||||
|
:members:
|
||||||
41
Doc/src/cipher/arc4.rst
Normal file
41
Doc/src/cipher/arc4.rst
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
ARC4
|
||||||
|
====
|
||||||
|
|
||||||
|
ARC4_ (Alleged RC4) is an implementation of RC4 (Rivest's Cipher version 4),
|
||||||
|
a symmetric stream cipher designed by Ron Rivest in 1987.
|
||||||
|
|
||||||
|
The cipher started as a proprietary design, that was reverse engineered and
|
||||||
|
anonymously posted on Usenet in 1994. The company that owns RC4 (RSA Data
|
||||||
|
Inc.) never confirmed the correctness of the leaked algorithm.
|
||||||
|
|
||||||
|
Unlike RC2, the company has never published the full specification of RC4,
|
||||||
|
of whom it still holds the trademark.
|
||||||
|
|
||||||
|
ARC4 keys can vary in length from 40 to 2048 bits.
|
||||||
|
|
||||||
|
One problem of ARC4 is that it does not take a nonce or an IV.
|
||||||
|
If it is required to encrypt multiple messages with the same long-term key, a
|
||||||
|
distinct independent nonce must be created for each message, and a short-term
|
||||||
|
key must be derived from the combination of the long-term key and the nonce.
|
||||||
|
Due to the weak key scheduling algorithm of RC2, the combination must be
|
||||||
|
carried out with a complex function (e.g. a cryptographic hash) and not by
|
||||||
|
simply concatenating key and nonce.
|
||||||
|
|
||||||
|
**If you need a stream cipher, use Salsa20, not ARC4. This module is only provided for legacy purposes.**
|
||||||
|
|
||||||
|
As an example, encryption can be done as follows::
|
||||||
|
|
||||||
|
>>> from Crypto.Cipher import ARC4
|
||||||
|
>>> from Crypto.Hash import SHA
|
||||||
|
>>> from Crypto.Random import get_random_bytes
|
||||||
|
>>>
|
||||||
|
>>> key = b'Very long and confidential key'
|
||||||
|
>>> nonce = get_random_bytes(16)
|
||||||
|
>>> tempkey = SHA.new(key+nonce).digest()
|
||||||
|
>>> cipher = ARC4.new(tempkey)
|
||||||
|
>>> msg = nonce + cipher.encrypt(b'Open the pod bay doors, HAL')
|
||||||
|
|
||||||
|
.. _ARC4: http://en.wikipedia.org/wiki/RC4
|
||||||
|
|
||||||
|
.. automodule:: Crypto.Cipher.ARC4
|
||||||
|
:members:
|
||||||
31
Doc/src/cipher/blowfish.rst
Normal file
31
Doc/src/cipher/blowfish.rst
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
Blowfish
|
||||||
|
========
|
||||||
|
|
||||||
|
Blowfish_ is a symmetric block cipher designed by Bruce Schneier.
|
||||||
|
|
||||||
|
It has a fixed data block size of 8 bytes and its keys can vary in length
|
||||||
|
from 32 to 448 bits (4 to 56 bytes).
|
||||||
|
|
||||||
|
Blowfish is deemed secure and it is fast. However, its keys should be chosen
|
||||||
|
to be big enough to withstand a brute force attack (e.g. at least 16 bytes).
|
||||||
|
|
||||||
|
**Use AES, not Blowfish. This module is provided only for legacy purposes.**
|
||||||
|
|
||||||
|
As an example, encryption can be done as follows::
|
||||||
|
|
||||||
|
>>> from Crypto.Cipher import Blowfish
|
||||||
|
>>> from struct import pack
|
||||||
|
>>>
|
||||||
|
>>> bs = Blowfish.block_size
|
||||||
|
>>> key = b'An arbitrarily long key'
|
||||||
|
>>> cipher = Blowfish.new(key, Blowfish.MODE_CBC)
|
||||||
|
>>> plaintext = b'docendo discimus '
|
||||||
|
>>> plen = bs - len(plaintext) % bs
|
||||||
|
>>> padding = [plen]*plen
|
||||||
|
>>> padding = pack('b'*plen, *padding)
|
||||||
|
>>> msg = cipher.iv + cipher.encrypt(plaintext + padding)
|
||||||
|
|
||||||
|
.. _Blowfish: http://www.schneier.com/blowfish.html
|
||||||
|
|
||||||
|
.. automodule:: Crypto.Cipher.Blowfish
|
||||||
|
:members:
|
||||||
34
Doc/src/cipher/cast.rst
Normal file
34
Doc/src/cipher/cast.rst
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
CAST-128
|
||||||
|
========
|
||||||
|
|
||||||
|
CAST-128_ (or CAST5) is a symmetric block cipher specified in RFC2144_.
|
||||||
|
|
||||||
|
It has a fixed data block size of 8 bytes. Its key can vary in length
|
||||||
|
from 40 to 128 bits.
|
||||||
|
|
||||||
|
CAST is deemed to be cryptographically secure, but its usage is not widespread.
|
||||||
|
Keys of sufficient length should be used to prevent brute force attacks
|
||||||
|
(128 bits are recommended).
|
||||||
|
|
||||||
|
**Use AES, not CAST. This module is only provided for legacy purposes.**
|
||||||
|
|
||||||
|
As an example, encryption can be done as follows:
|
||||||
|
|
||||||
|
>>> from Crypto.Cipher import CAST
|
||||||
|
>>>
|
||||||
|
>>> key = b'Sixteen byte key'
|
||||||
|
>>> cipher = CAST.new(key, CAST.MODE_OPENPGP)
|
||||||
|
>>> plaintext = b'sona si latine loqueris '
|
||||||
|
>>> msg = cipher.encrypt(plaintext)
|
||||||
|
>>>
|
||||||
|
...
|
||||||
|
>>> eiv = msg[:CAST.block_size+2]
|
||||||
|
>>> ciphertext = msg[CAST.block_size+2:]
|
||||||
|
>>> cipher = CAST.new(key, CAST.MODE_OPENPGP, eiv)
|
||||||
|
>>> print cipher.decrypt(ciphertext)
|
||||||
|
|
||||||
|
.. _CAST-128: http://en.wikipedia.org/wiki/CAST-128
|
||||||
|
.. _RFC2144: http://tools.ietf.org/html/rfc2144
|
||||||
|
|
||||||
|
.. automodule:: Crypto.Cipher.CAST
|
||||||
|
:members:
|
||||||
48
Doc/src/cipher/pkcs1_v1_5.rst
Normal file
48
Doc/src/cipher/pkcs1_v1_5.rst
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
PKCS#1 v1.5 encryption (RSA)
|
||||||
|
============================
|
||||||
|
|
||||||
|
See RFC8017__ or the `original RSA Labs specification`__ .
|
||||||
|
|
||||||
|
This scheme is more properly called ``RSAES-PKCS1-v1_5``.
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
If you are designing a new protocol, consider using the more robust :doc:`oaep`.
|
||||||
|
|
||||||
|
As an example, a sender may encrypt a message in this way::
|
||||||
|
|
||||||
|
>>> from Crypto.Cipher import PKCS1_v1_5
|
||||||
|
>>> from Crypto.PublicKey import RSA
|
||||||
|
>>> from Crypto.Hash import SHA
|
||||||
|
>>>
|
||||||
|
>>> message = b'To be encrypted'
|
||||||
|
>>> h = SHA.new(message)
|
||||||
|
>>>
|
||||||
|
>>> key = RSA.importKey(open('pubkey.der').read())
|
||||||
|
>>> cipher = PKCS1_v1_5.new(key)
|
||||||
|
>>> ciphertext = cipher.encrypt(message+h.digest())
|
||||||
|
|
||||||
|
At the receiver side, decryption can be done using the private part of
|
||||||
|
the RSA key::
|
||||||
|
|
||||||
|
>>> From Crypto.Hash import SHA
|
||||||
|
>>> from Crypto import Random
|
||||||
|
>>>
|
||||||
|
>>> key = RSA.importKey(open('privkey.der').read())
|
||||||
|
>>>
|
||||||
|
>>> dsize = SHA.digest_size
|
||||||
|
>>> sentinel = Random.new().read(15+dsize) # Let's assume that average data length is 15
|
||||||
|
>>>
|
||||||
|
>>> cipher = PKCS1_v1_5.new(key)
|
||||||
|
>>> message = cipher.decrypt(ciphertext, sentinel)
|
||||||
|
>>>
|
||||||
|
>>> digest = SHA.new(message[:-dsize]).digest()
|
||||||
|
>>> if digest==message[-dsize:]: # Note how we DO NOT look for the sentinel
|
||||||
|
>>> print "Encryption was correct."
|
||||||
|
>>> else:
|
||||||
|
>>> print "Encryption was not correct."
|
||||||
|
|
||||||
|
.. __: https://tools.ietf.org/html/rfc8017
|
||||||
|
.. __: http://www.rsa.com/rsalabs/node.asp?id=2125.
|
||||||
|
|
||||||
|
.. automodule:: Crypto.Cipher.PKCS1_v1_5
|
||||||
|
:members:
|
||||||
|
|
@ -19,39 +19,16 @@
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
"""RC2 symmetric cipher
|
"""
|
||||||
|
Module's constants for the modes of operation supported with ARC2:
|
||||||
|
|
||||||
RC2_ (Rivest's Cipher version 2) is a symmetric block cipher designed
|
:var MODE_ECB: Electronic Code Book (ECB)
|
||||||
by Ron Rivest in 1987. The cipher started as a proprietary design,
|
:var MODE_CBC: Cipher-Block Chaining (CBC)
|
||||||
that was reverse engineered and anonymously posted on Usenet in 1996.
|
:var MODE_CFB: Cipher FeedBack (CFB)
|
||||||
For this reason, the algorithm was first called *Alleged* RC2 (ARC2),
|
:var MODE_OFB: Output FeedBack (OFB)
|
||||||
since the company that owned RC2 (RSA Data Inc.) did not confirm whether
|
:var MODE_CTR: CounTer Mode (CTR)
|
||||||
the details leaked into public domain were really correct.
|
:var MODE_OPENPGP: OpenPGP Mode
|
||||||
|
:var MODE_EAX: EAX Mode
|
||||||
The company eventually published its full specification in RFC2268_.
|
|
||||||
|
|
||||||
RC2 has a fixed data block size of 8 bytes. Length of its keys can vary from
|
|
||||||
8 to 128 bits. One particular property of RC2 is that the actual
|
|
||||||
cryptographic strength of the key (*effective key length*) can be reduced
|
|
||||||
via a parameter.
|
|
||||||
|
|
||||||
Even though RC2 is not cryptographically broken, it has not been analyzed as
|
|
||||||
thoroughly as AES, which is also faster than RC2.
|
|
||||||
|
|
||||||
**Use AES, not ARC2. This module is only provided for legacy purposes.**
|
|
||||||
|
|
||||||
As an example, encryption can be done as follows:
|
|
||||||
|
|
||||||
>>> from Crypto.Cipher import ARC2
|
|
||||||
>>>
|
|
||||||
>>> key = b'Sixteen byte key'
|
|
||||||
>>> cipher = ARC2.new(key, ARC2.MODE_CFB)
|
|
||||||
>>> msg = cipher.iv + cipher.encrypt(b'Attack at dawn')
|
|
||||||
|
|
||||||
.. _RC2: http://en.wikipedia.org/wiki/RC2
|
|
||||||
.. _RFC2268: http://tools.ietf.org/html/rfc2268
|
|
||||||
|
|
||||||
:undocumented: __package__
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -118,101 +95,76 @@ def _create_base_cipher(dict_parameters):
|
||||||
|
|
||||||
|
|
||||||
def new(key, mode, *args, **kwargs):
|
def new(key, mode, *args, **kwargs):
|
||||||
"""Create a new RC2 cipher
|
"""Create a new RC2 cipher.
|
||||||
|
|
||||||
:Parameters:
|
:param key:
|
||||||
key : byte string
|
|
||||||
The secret key to use in the symmetric cipher.
|
The secret key to use in the symmetric cipher.
|
||||||
Its length can vary from 5 to 128 bytes.
|
Its length can vary from 5 to 128 bytes.
|
||||||
|
:type key: byte string
|
||||||
|
|
||||||
mode : a *MODE_** constant
|
:param mode:
|
||||||
The chaining mode to use for encryption or decryption.
|
The chaining mode to use for encryption or decryption.
|
||||||
|
:type mode: One of the supported ``MODE_*`` constants
|
||||||
|
|
||||||
:Keywords:
|
:Keyword Arguments:
|
||||||
iv : byte string
|
* *iv* (``byte string``) --
|
||||||
(*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`).
|
(Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``,
|
||||||
|
and ``MODE_OPENPGP`` modes).
|
||||||
|
|
||||||
The initialization vector to use for encryption or decryption.
|
The initialization vector to use for encryption or decryption.
|
||||||
|
|
||||||
For `MODE_OPENPGP`, IV must be 8 bytes long for encryption
|
For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 8 bytes long.
|
||||||
and 10 bytes for decryption (in the latter case, it is
|
|
||||||
actually the *encrypted* IV which was prefixed to the ciphertext).
|
|
||||||
|
|
||||||
For all other modes, it must be 8 bytes long.
|
For ``MODE_OPENPGP`` mode only,
|
||||||
|
it must be 8 bytes long for encryption
|
||||||
|
and 10 bytes for decryption (in the latter case, it is
|
||||||
|
actually the *encrypted* IV which was prefixed to the ciphertext).
|
||||||
|
|
||||||
If not provided, a random byte string will be generated (you
|
If not provided, a random byte string is generated (you must then
|
||||||
must read it back via the ``iv`` attribute of the cipher).
|
read its value with the :attr:`iv` attribute).
|
||||||
|
|
||||||
nonce : byte string
|
* *nonce* (``byte string``) --
|
||||||
(*Only* `MODE_EAX` and `MODE_CTR`).
|
(Only applicable for ``MODE_EAX`` and ``MODE_CTR``).
|
||||||
A value that must never be reused for any other encryption done with
|
|
||||||
this key.
|
|
||||||
|
|
||||||
For `MODE_CTR`, its length must be in the range ``[0..7]``.
|
A value that must never be reused for any other encryption done
|
||||||
|
with this key.
|
||||||
|
|
||||||
For `MODE_EAX`, there are no restrictions, but it is recommended to
|
For ``MODE_EAX`` there are no
|
||||||
use at least 16 bytes.
|
restrictions on its length (recommended: **16** bytes).
|
||||||
|
|
||||||
If not provided for `MODE_EAX`, a random byte string will be
|
For ``MODE_CTR``, its length must be in the range **[0..7]**.
|
||||||
generated (you must read it back via the ``nonce`` attribute
|
|
||||||
of the cipher).
|
|
||||||
|
|
||||||
mac_len : integer
|
If not provided for ``MODE_EAX``, a random byte string is generated (you
|
||||||
(*Only* `MODE_EAX`). Length of the authentication tag, in bytes.
|
can read it back via the ``nonce`` attribute).
|
||||||
It must be no larger than 8 (which is the default).
|
|
||||||
|
|
||||||
segment_size : integer
|
* *segment_size* (``integer``) --
|
||||||
(*Only* `MODE_CFB`).
|
(Only ``MODE_CFB``).The number of **bits** the plaintext and ciphertext
|
||||||
The number of **bits** the plaintext and ciphertext are segmented in.
|
are segmented in. It must be a multiple of 8.
|
||||||
It must be a multiple of 8. If not specified,
|
If not specified, it will be assumed to be 8.
|
||||||
it will be assumed to be 8.
|
|
||||||
|
|
||||||
initial_value : integer
|
* *mac_len* : (``integer``) --
|
||||||
(*Only* `MODE_CTR`). The initial value for the counter within
|
(Only ``MODE_EAX``)
|
||||||
the counter block. By default it is 0.
|
Length of the authentication tag, in bytes.
|
||||||
|
It must be no longer than 8 (default).
|
||||||
|
|
||||||
effective_keylen : integer
|
* *initial_value* : (``integer``) --
|
||||||
Maximum cryptographic strength of the key, in **bits**.
|
(Only ``MODE_CTR``). The initial value for the counter within
|
||||||
It can vary from 40 to 1024. The default value is 1024.
|
the counter block. By default it is **0**.
|
||||||
|
|
||||||
:Return: an RC2 cipher object, of the applicable mode:
|
|
||||||
|
|
||||||
- CBC_ mode
|
|
||||||
- CFB_ mode
|
|
||||||
- CTR_ mode
|
|
||||||
- EAX_ mode
|
|
||||||
- ECB_ mode
|
|
||||||
- OFB_ mode
|
|
||||||
- OpenPgp_ mode
|
|
||||||
|
|
||||||
.. _CBC: Crypto.Cipher._mode_cbc.CbcMode-class.html
|
|
||||||
.. _CFB: Crypto.Cipher._mode_cfb.CfbMode-class.html
|
|
||||||
.. _CTR: Crypto.Cipher._mode_ctr.CtrMode-class.html
|
|
||||||
.. _EAX: Crypto.Cipher._mode_eax.EaxMode-class.html
|
|
||||||
.. _ECB: Crypto.Cipher._mode_ecb.EcbMode-class.html
|
|
||||||
.. _OFB: Crypto.Cipher._mode_ofb.OfbMode-class.html
|
|
||||||
.. _OpenPgp: Crypto.Cipher._mode_openpgp.OpenPgpMode-class.html
|
|
||||||
|
|
||||||
|
:Return: an ARC2 object, of the applicable mode.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
|
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
|
||||||
|
|
||||||
#: Electronic Code Book (ECB). See `Crypto.Cipher._mode_ecb.EcbMode`.
|
|
||||||
MODE_ECB = 1
|
MODE_ECB = 1
|
||||||
#: Cipher-Block Chaining (CBC). See `Crypto.Cipher._mode_cbc.CbcMode`.
|
|
||||||
MODE_CBC = 2
|
MODE_CBC = 2
|
||||||
#: Cipher FeedBack (CFB). See `Crypto.Cipher._mode_cfb.CfbMode`.
|
|
||||||
MODE_CFB = 3
|
MODE_CFB = 3
|
||||||
#: Output FeedBack (OFB). See `Crypto.Cipher._mode_ofb.OfbMode`.
|
|
||||||
MODE_OFB = 5
|
MODE_OFB = 5
|
||||||
#: CounTer Mode (CTR). See `Crypto.Cipher._mode_ctr.CtrMode`.
|
|
||||||
MODE_CTR = 6
|
MODE_CTR = 6
|
||||||
#: OpenPGP Mode. See `Crypto.Cipher._mode_openpgp.OpenPgpMode`.
|
|
||||||
MODE_OPENPGP = 7
|
MODE_OPENPGP = 7
|
||||||
#: EAX Mode. See `Crypto.Cipher._mode_eax.EaxMode`.
|
|
||||||
MODE_EAX = 9
|
MODE_EAX = 9
|
||||||
|
|
||||||
#: Size of a data block (in bytes)
|
# Size of a data block (in bytes)
|
||||||
block_size = 8
|
block_size = 8
|
||||||
#: Size of a key (in bytes)
|
# Size of a key (in bytes)
|
||||||
key_size = xrange(5, 128 + 1)
|
key_size = xrange(5, 128 + 1)
|
||||||
|
|
|
||||||
|
|
@ -19,46 +19,6 @@
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
"""ARC4 symmetric cipher
|
|
||||||
|
|
||||||
ARC4_ (Alleged RC4) is an implementation of RC4 (Rivest's Cipher version 4),
|
|
||||||
a symmetric stream cipher designed by Ron Rivest in 1987.
|
|
||||||
|
|
||||||
The cipher started as a proprietary design, that was reverse engineered and
|
|
||||||
anonymously posted on Usenet in 1994. The company that owns RC4 (RSA Data
|
|
||||||
Inc.) never confirmed the correctness of the leaked algorithm.
|
|
||||||
|
|
||||||
Unlike RC2, the company has never published the full specification of RC4,
|
|
||||||
of whom it still holds the trademark.
|
|
||||||
|
|
||||||
ARC4 keys can vary in length from 40 to 2048 bits.
|
|
||||||
|
|
||||||
One problem of ARC4 is that it does not take a nonce or an IV.
|
|
||||||
If it is required to encrypt multiple messages with the same long-term key, a
|
|
||||||
distinct independent nonce must be created for each message, and a short-term
|
|
||||||
key must be derived from the combination of the long-term key and the nonce.
|
|
||||||
Due to the weak key scheduling algorithm of RC2, the combination must be
|
|
||||||
carried out with a complex function (e.g. a cryptographic hash) and not by
|
|
||||||
simply concatenating key and nonce.
|
|
||||||
|
|
||||||
**Use ChaCha20, not ARC4. This module is only provided for legacy purposes.**
|
|
||||||
|
|
||||||
As an example, encryption can be done as follows:
|
|
||||||
|
|
||||||
>>> from Crypto.Cipher import ARC4
|
|
||||||
>>> from Crypto.Hash import SHA
|
|
||||||
>>> from Crypto.Random import get_random_bytes
|
|
||||||
>>>
|
|
||||||
>>> key = b'Very long and confidential key'
|
|
||||||
>>> nonce = get_random_bytes(16)
|
|
||||||
>>> tempkey = SHA.new(key+nonce).digest()
|
|
||||||
>>> cipher = ARC4.new(tempkey)
|
|
||||||
>>> msg = nonce + cipher.encrypt(b'Open the pod bay doors, HAL')
|
|
||||||
|
|
||||||
.. _ARC4: http://en.wikipedia.org/wiki/RC4
|
|
||||||
|
|
||||||
:undocumented: __package__
|
|
||||||
"""
|
|
||||||
|
|
||||||
from Crypto.Util.py3compat import b
|
from Crypto.Util.py3compat import b
|
||||||
|
|
||||||
|
|
@ -77,7 +37,9 @@ _raw_arc4_lib = load_pycryptodome_raw_lib("Crypto.Cipher._ARC4", """
|
||||||
|
|
||||||
|
|
||||||
class ARC4Cipher:
|
class ARC4Cipher:
|
||||||
"""ARC4 cipher object"""
|
"""ARC4 cipher object. Do not create it directly. Use
|
||||||
|
:func:`Crypto.Cipher.ARC4.new` instead.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self, key, *args, **kwargs):
|
def __init__(self, key, *args, **kwargs):
|
||||||
"""Initialize an ARC4 cipher object
|
"""Initialize an ARC4 cipher object
|
||||||
|
|
@ -118,11 +80,10 @@ class ARC4Cipher:
|
||||||
def encrypt(self, plaintext):
|
def encrypt(self, plaintext):
|
||||||
"""Encrypt a piece of data.
|
"""Encrypt a piece of data.
|
||||||
|
|
||||||
:Parameters:
|
:param plaintext: The data to encrypt, of any size.
|
||||||
plaintext : byte string
|
:type plaintext: byte string
|
||||||
The piece of data to encrypt. It can be of any size.
|
:returns: the encrypted byte string, of equal length as the
|
||||||
:Return: the encrypted data (byte string, as long as the
|
plaintext.
|
||||||
plaintext).
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
expect_byte_string(plaintext)
|
expect_byte_string(plaintext)
|
||||||
|
|
@ -138,12 +99,12 @@ class ARC4Cipher:
|
||||||
def decrypt(self, ciphertext):
|
def decrypt(self, ciphertext):
|
||||||
"""Decrypt a piece of data.
|
"""Decrypt a piece of data.
|
||||||
|
|
||||||
:Parameters:
|
:param ciphertext: The data to decrypt, of any size.
|
||||||
ciphertext : byte string
|
:type ciphertext: byte string
|
||||||
The piece of data to decrypt. It can be of any size.
|
:returns: the decrypted byte string, of equal length as the
|
||||||
:Return: the decrypted data (byte string, as long as the
|
ciphertext.
|
||||||
ciphertext).
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return self.encrypt(ciphertext)
|
return self.encrypt(ciphertext)
|
||||||
except ValueError, e:
|
except ValueError, e:
|
||||||
|
|
@ -151,21 +112,21 @@ class ARC4Cipher:
|
||||||
|
|
||||||
|
|
||||||
def new(key, *args, **kwargs):
|
def new(key, *args, **kwargs):
|
||||||
"""Create a new ARC4 cipher
|
"""Create a new ARC4 cipher.
|
||||||
|
|
||||||
:Parameters:
|
:param key:
|
||||||
key : byte string
|
|
||||||
The secret key to use in the symmetric cipher.
|
The secret key to use in the symmetric cipher.
|
||||||
Its length must be in the range ``[5..256]``.
|
Its length must be in the range ``[5..256]``.
|
||||||
The recommended length is 16 bytes.
|
The recommended length is 16 bytes.
|
||||||
|
:type key: byte string
|
||||||
|
|
||||||
:Keywords:
|
:Keyword Arguments:
|
||||||
drop : integer
|
* *drop* (``integer``) --
|
||||||
The amount of bytes to discard from the initial part of the keystream.
|
The amount of bytes to discard from the initial part of the keystream.
|
||||||
In fact, such part has been found to be distinguishable from random
|
In fact, such part has been found to be distinguishable from random
|
||||||
data (while it shouldn't) and also correlated to key.
|
data (while it shouldn't) and also correlated to key.
|
||||||
|
|
||||||
The recommended value is 3072_ bytes. The default value is 0.
|
The recommended value is 3072_ bytes. The default value is 0.
|
||||||
|
|
||||||
:Return: an `ARC4Cipher` object
|
:Return: an `ARC4Cipher` object
|
||||||
|
|
||||||
|
|
@ -173,7 +134,7 @@ def new(key, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
return ARC4Cipher(key, *args, **kwargs)
|
return ARC4Cipher(key, *args, **kwargs)
|
||||||
|
|
||||||
#: Size of a data block (in bytes)
|
# Size of a data block (in bytes)
|
||||||
block_size = 1
|
block_size = 1
|
||||||
#: Size of a key (in bytes)
|
# Size of a key (in bytes)
|
||||||
key_size = xrange(5, 256+1)
|
key_size = xrange(5, 256+1)
|
||||||
|
|
|
||||||
|
|
@ -19,35 +19,16 @@
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
"""Blowfish symmetric cipher
|
"""
|
||||||
|
Module's constants for the modes of operation supported with Blowfish:
|
||||||
|
|
||||||
Blowfish_ is a symmetric block cipher designed by Bruce Schneier.
|
:var MODE_ECB: Electronic Code Book (ECB)
|
||||||
|
:var MODE_CBC: Cipher-Block Chaining (CBC)
|
||||||
It has a fixed data block size of 8 bytes and its keys can vary in length
|
:var MODE_CFB: Cipher FeedBack (CFB)
|
||||||
from 32 to 448 bits (4 to 56 bytes).
|
:var MODE_OFB: Output FeedBack (OFB)
|
||||||
|
:var MODE_CTR: CounTer Mode (CTR)
|
||||||
Blowfish is deemed secure and it is fast. However, its keys should be chosen
|
:var MODE_OPENPGP: OpenPGP Mode
|
||||||
to be big enough to withstand a brute force attack (e.g. at least 16 bytes).
|
:var MODE_EAX: EAX Mode
|
||||||
|
|
||||||
**Use AES, not Blowfish. This module is provided only for legacy purposes.**
|
|
||||||
|
|
||||||
As an example, encryption can be done as follows:
|
|
||||||
|
|
||||||
>>> from Crypto.Cipher import Blowfish
|
|
||||||
>>> from struct import pack
|
|
||||||
>>>
|
|
||||||
>>> bs = Blowfish.block_size
|
|
||||||
>>> key = b'An arbitrarily long key'
|
|
||||||
>>> cipher = Blowfish.new(key, Blowfish.MODE_CBC)
|
|
||||||
>>> plaintext = b'docendo discimus '
|
|
||||||
>>> plen = bs - len(plaintext) % bs
|
|
||||||
>>> padding = [plen]*plen
|
|
||||||
>>> padding = pack('b'*plen, *padding)
|
|
||||||
>>> msg = cipher.iv + cipher.encrypt(plaintext + padding)
|
|
||||||
|
|
||||||
.. _Blowfish: http://www.schneier.com/blowfish.html
|
|
||||||
|
|
||||||
:undocumented: __package__
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -105,91 +86,74 @@ def _create_base_cipher(dict_parameters):
|
||||||
def new(key, mode, *args, **kwargs):
|
def new(key, mode, *args, **kwargs):
|
||||||
"""Create a new Blowfish cipher
|
"""Create a new Blowfish cipher
|
||||||
|
|
||||||
:Parameters:
|
:param key:
|
||||||
key : byte string
|
|
||||||
The secret key to use in the symmetric cipher.
|
The secret key to use in the symmetric cipher.
|
||||||
Its length can vary from 5 to 56 bytes.
|
Its length can vary from 5 to 56 bytes.
|
||||||
|
:type key: byte string
|
||||||
|
|
||||||
mode : a *MODE_** constant
|
:param mode:
|
||||||
The chaining mode to use for encryption or decryption.
|
The chaining mode to use for encryption or decryption.
|
||||||
|
:type mode: One of the supported ``MODE_*`` constants
|
||||||
|
|
||||||
:Keywords:
|
:Keyword Arguments:
|
||||||
iv : byte string
|
* *iv* (``byte string``) --
|
||||||
(*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`).
|
(Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``,
|
||||||
|
and ``MODE_OPENPGP`` modes).
|
||||||
|
|
||||||
The initialization vector to use for encryption or decryption.
|
The initialization vector to use for encryption or decryption.
|
||||||
|
|
||||||
For `MODE_OPENPGP`, IV must be 8 bytes long for encryption
|
For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 8 bytes long.
|
||||||
and 10 bytes for decryption (in the latter case, it is
|
|
||||||
actually the *encrypted* IV which was prefixed to the ciphertext).
|
|
||||||
|
|
||||||
For all other modes, it must be 8 bytes long.
|
For ``MODE_OPENPGP`` mode only,
|
||||||
|
it must be 8 bytes long for encryption
|
||||||
|
and 10 bytes for decryption (in the latter case, it is
|
||||||
|
actually the *encrypted* IV which was prefixed to the ciphertext).
|
||||||
|
|
||||||
If not provided, a random byte string will be generated (you must
|
If not provided, a random byte string is generated (you must then
|
||||||
read it back via the ``iv`` attribute).
|
read its value with the :attr:`iv` attribute).
|
||||||
|
|
||||||
nonce : byte string
|
* *nonce* (``byte string``) --
|
||||||
(*Only* `MODE_EAX` and `MODE_CTR`).
|
(Only applicable for ``MODE_EAX`` and ``MODE_CTR``).
|
||||||
A value that must never be reused for any other encryption.
|
|
||||||
|
|
||||||
For `MODE_CTR`, its length must be in the range ``[0..7]``.
|
A value that must never be reused for any other encryption done
|
||||||
|
with this key.
|
||||||
|
|
||||||
For `MODE_EAX`, there are no restrictions, but it is recommended to
|
For ``MODE_EAX`` there are no
|
||||||
use at least 16 bytes.
|
restrictions on its length (recommended: **16** bytes).
|
||||||
|
|
||||||
If not provided for `MODE_EAX`, a 16 byte random string will be used
|
For ``MODE_CTR``, its length must be in the range **[0..7]**.
|
||||||
(you can read it back via the ``nonce`` attribute).
|
|
||||||
|
|
||||||
mac_len : integer
|
If not provided for ``MODE_EAX``, a random byte string is generated (you
|
||||||
(*Only* `MODE_EAX`). Length of the authentication tag, in bytes.
|
can read it back via the ``nonce`` attribute).
|
||||||
It must be no larger than 8 (which is the default).
|
|
||||||
|
|
||||||
segment_size : integer
|
* *segment_size* (``integer``) --
|
||||||
(*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext
|
(Only ``MODE_CFB``).The number of **bits** the plaintext and ciphertext
|
||||||
are segmented in. It must be a multiple of 8.
|
are segmented in. It must be a multiple of 8.
|
||||||
If not specified, it will be assumed to be 8.
|
If not specified, it will be assumed to be 8.
|
||||||
|
|
||||||
initial_value : integer
|
* *mac_len* : (``integer``) --
|
||||||
(*Only* `MODE_CTR`). The initial value for the counter within
|
(Only ``MODE_EAX``)
|
||||||
the counter block. By default it is 0.
|
Length of the authentication tag, in bytes.
|
||||||
|
It must be no longer than 8 (default).
|
||||||
|
|
||||||
:Return: a Blowfish cipher object, of the applicable mode:
|
* *initial_value* : (``integer``) --
|
||||||
|
(Only ``MODE_CTR``). The initial value for the counter within
|
||||||
|
the counter block. By default it is **0**.
|
||||||
|
|
||||||
- CBC_ mode
|
:Return: a Blowfish object, of the applicable mode.
|
||||||
- CFB_ mode
|
|
||||||
- CTR_ mode
|
|
||||||
- EAX_ mode
|
|
||||||
- ECB_ mode
|
|
||||||
- OFB_ mode
|
|
||||||
- OpenPgp_ mode
|
|
||||||
|
|
||||||
.. _CBC: Crypto.Cipher._mode_cbc.CbcMode-class.html
|
|
||||||
.. _CFB: Crypto.Cipher._mode_cfb.CfbMode-class.html
|
|
||||||
.. _CTR: Crypto.Cipher._mode_ctr.CtrMode-class.html
|
|
||||||
.. _EAX: Crypto.Cipher._mode_eax.EaxMode-class.html
|
|
||||||
.. _ECB: Crypto.Cipher._mode_ecb.EcbMode-class.html
|
|
||||||
.. _OFB: Crypto.Cipher._mode_ofb.OfbMode-class.html
|
|
||||||
.. _OpenPgp: Crypto.Cipher._mode_openpgp.OpenPgpMode-class.html
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
|
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
|
||||||
|
|
||||||
#: Electronic Code Book (ECB). See `Crypto.Cipher._mode_ecb.EcbMode`.
|
|
||||||
MODE_ECB = 1
|
MODE_ECB = 1
|
||||||
#: Cipher-Block Chaining (CBC). See `Crypto.Cipher._mode_cbc.CbcMode`.
|
|
||||||
MODE_CBC = 2
|
MODE_CBC = 2
|
||||||
#: Cipher FeedBack (CFB). See `Crypto.Cipher._mode_cfb.CfbMode`.
|
|
||||||
MODE_CFB = 3
|
MODE_CFB = 3
|
||||||
#: Output FeedBack (OFB). See `Crypto.Cipher._mode_ofb.OfbMode`.
|
|
||||||
MODE_OFB = 5
|
MODE_OFB = 5
|
||||||
#: CounTer Mode (CTR). See `Crypto.Cipher._mode_ctr.CtrMode`.
|
|
||||||
MODE_CTR = 6
|
MODE_CTR = 6
|
||||||
#: OpenPGP Mode. See `Crypto.Cipher._mode_openpgp.OpenPgpMode`.
|
|
||||||
MODE_OPENPGP = 7
|
MODE_OPENPGP = 7
|
||||||
#: EAX Mode. See `Crypto.Cipher._mode_eax.EaxMode`.
|
|
||||||
MODE_EAX = 9
|
MODE_EAX = 9
|
||||||
|
|
||||||
#: Size of a data block (in bytes)
|
# Size of a data block (in bytes)
|
||||||
block_size = 8
|
block_size = 8
|
||||||
#: Size of a key (in bytes)
|
# Size of a key (in bytes)
|
||||||
key_size = xrange(5, 56 + 1)
|
key_size = xrange(5, 56 + 1)
|
||||||
|
|
|
||||||
|
|
@ -19,38 +19,16 @@
|
||||||
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
"""CAST-128 symmetric cipher
|
"""
|
||||||
|
Module's constants for the modes of operation supported with CAST:
|
||||||
|
|
||||||
CAST-128_ (or CAST5) is a symmetric block cipher specified in RFC2144_.
|
:var MODE_ECB: Electronic Code Book (ECB)
|
||||||
|
:var MODE_CBC: Cipher-Block Chaining (CBC)
|
||||||
It has a fixed data block size of 8 bytes. Its key can vary in length
|
:var MODE_CFB: Cipher FeedBack (CFB)
|
||||||
from 40 to 128 bits.
|
:var MODE_OFB: Output FeedBack (OFB)
|
||||||
|
:var MODE_CTR: CounTer Mode (CTR)
|
||||||
CAST is deemed to be cryptographically secure, but its usage is not widespread.
|
:var MODE_OPENPGP: OpenPGP Mode
|
||||||
Keys of sufficient length should be used to prevent brute force attacks
|
:var MODE_EAX: EAX Mode
|
||||||
(128 bits are recommended).
|
|
||||||
|
|
||||||
**Use AES, not CAST. This module is only provided for legacy purposes.**
|
|
||||||
|
|
||||||
As an example, encryption can be done as follows:
|
|
||||||
|
|
||||||
>>> from Crypto.Cipher import CAST
|
|
||||||
>>>
|
|
||||||
>>> key = b'Sixteen byte key'
|
|
||||||
>>> cipher = CAST.new(key, CAST.MODE_OPENPGP)
|
|
||||||
>>> plaintext = b'sona si latine loqueris '
|
|
||||||
>>> msg = cipher.encrypt(plaintext)
|
|
||||||
>>>
|
|
||||||
...
|
|
||||||
>>> eiv = msg[:CAST.block_size+2]
|
|
||||||
>>> ciphertext = msg[CAST.block_size+2:]
|
|
||||||
>>> cipher = CAST.new(key, CAST.MODE_OPENPGP, eiv)
|
|
||||||
>>> print cipher.decrypt(ciphertext)
|
|
||||||
|
|
||||||
.. _CAST-128: http://en.wikipedia.org/wiki/CAST-128
|
|
||||||
.. _RFC2144: http://tools.ietf.org/html/rfc2144
|
|
||||||
|
|
||||||
:undocumented: __package__
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
@ -108,95 +86,76 @@ def _create_base_cipher(dict_parameters):
|
||||||
|
|
||||||
|
|
||||||
def new(key, mode, *args, **kwargs):
|
def new(key, mode, *args, **kwargs):
|
||||||
"""Create a new CAST-128 cipher
|
"""Create a new CAST cipher
|
||||||
|
|
||||||
:Parameters:
|
:param key:
|
||||||
key : byte string
|
|
||||||
The secret key to use in the symmetric cipher.
|
The secret key to use in the symmetric cipher.
|
||||||
Its length may vary from 5 to 16 bytes.
|
Its length can vary from 5 to 16 bytes.
|
||||||
The recommended length is 16 bytes.
|
:type key: byte string
|
||||||
|
|
||||||
mode : a *MODE_** constant
|
:param mode:
|
||||||
The chaining mode to use for encryption or decryption.
|
The chaining mode to use for encryption or decryption.
|
||||||
|
:type mode: One of the supported ``MODE_*`` constants
|
||||||
|
|
||||||
:Keywords:
|
:Keyword Arguments:
|
||||||
iv : byte string
|
* *iv* (``byte string``) --
|
||||||
(*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`).
|
(Only applicable for ``MODE_CBC``, ``MODE_CFB``, ``MODE_OFB``,
|
||||||
|
and ``MODE_OPENPGP`` modes).
|
||||||
|
|
||||||
The initialization vector to use for encryption or decryption.
|
The initialization vector to use for encryption or decryption.
|
||||||
|
|
||||||
For `MODE_OPENPGP`, IV must be 8 bytes long for encryption
|
For ``MODE_CBC``, ``MODE_CFB``, and ``MODE_OFB`` it must be 8 bytes long.
|
||||||
and 10 bytes for decryption (in the latter case, it is
|
|
||||||
actually the *encrypted* IV which was prefixed to the ciphertext).
|
|
||||||
|
|
||||||
For all other modes, it must be 8 bytes long.
|
For ``MODE_OPENPGP`` mode only,
|
||||||
|
it must be 8 bytes long for encryption
|
||||||
|
and 10 bytes for decryption (in the latter case, it is
|
||||||
|
actually the *encrypted* IV which was prefixed to the ciphertext).
|
||||||
|
|
||||||
If not provided, a random byte string will be generated (you can
|
If not provided, a random byte string is generated (you must then
|
||||||
read it back via the ``iv`` attribute).
|
read its value with the :attr:`iv` attribute).
|
||||||
|
|
||||||
nonce : byte string
|
* *nonce* (``byte string``) --
|
||||||
(*Only* `MODE_EAX` and `MODE_CTR`)
|
(Only applicable for ``MODE_EAX`` and ``MODE_CTR``).
|
||||||
A mandatory value that must never be reused for any other encryption.
|
|
||||||
|
|
||||||
For `MODE_CTR`, its length must be in the range ``[0..7]``.
|
A value that must never be reused for any other encryption done
|
||||||
|
with this key.
|
||||||
|
|
||||||
For `MODE_EAX`, there are no restrictions, but it is recommended to
|
For ``MODE_EAX`` there are no
|
||||||
use at least 16 bytes.
|
restrictions on its length (recommended: **16** bytes).
|
||||||
|
|
||||||
If not provided for `MODE_EAX`, a random 16 byte string will be
|
For ``MODE_CTR``, its length must be in the range **[0..7]**.
|
||||||
generated (you can read it back via the ``nonce`` attribute).
|
|
||||||
|
|
||||||
mac_len : integer
|
If not provided for ``MODE_EAX``, a random byte string is generated (you
|
||||||
(*Only* `MODE_EAX`). Length of the authentication tag, in bytes.
|
can read it back via the ``nonce`` attribute).
|
||||||
It must be no larger than 8 (which is the default).
|
|
||||||
|
|
||||||
segment_size : integer
|
* *segment_size* (``integer``) --
|
||||||
(*Only* `MODE_CFB`).The number of **bits** the plaintext and ciphertext
|
(Only ``MODE_CFB``).The number of **bits** the plaintext and ciphertext
|
||||||
are segmented in. It must be a multiple of 8.
|
are segmented in. It must be a multiple of 8.
|
||||||
If not specified, it will be assumed to be 8.
|
If not specified, it will be assumed to be 8.
|
||||||
|
|
||||||
initial_value : integer
|
* *mac_len* : (``integer``) --
|
||||||
(*Only* `MODE_CTR`). The initial value for the counter within
|
(Only ``MODE_EAX``)
|
||||||
the counter block. By default it is 0.
|
Length of the authentication tag, in bytes.
|
||||||
|
It must be no longer than 8 (default).
|
||||||
|
|
||||||
:Return: a CAST cipher object, of the applicable mode:
|
* *initial_value* : (``integer``) --
|
||||||
|
(Only ``MODE_CTR``). The initial value for the counter within
|
||||||
- CBC_ mode
|
the counter block. By default it is **0**.
|
||||||
- CFB_ mode
|
|
||||||
- CTR_ mode
|
|
||||||
- EAX_ mode
|
|
||||||
- ECB_ mode
|
|
||||||
- OFB_ mode
|
|
||||||
- OpenPgp_ mode
|
|
||||||
|
|
||||||
.. _CBC: Crypto.Cipher._mode_cbc.CbcMode-class.html
|
|
||||||
.. _CFB: Crypto.Cipher._mode_cfb.CfbMode-class.html
|
|
||||||
.. _CTR: Crypto.Cipher._mode_ctr.CtrMode-class.html
|
|
||||||
.. _EAX: Crypto.Cipher._mode_eax.EaxMode-class.html
|
|
||||||
.. _ECB: Crypto.Cipher._mode_ecb.EcbMode-class.html
|
|
||||||
.. _OFB: Crypto.Cipher._mode_ofb.OfbMode-class.html
|
|
||||||
.. _OpenPgp: Crypto.Cipher._mode_openpgp.OpenPgpMode-class.html
|
|
||||||
|
|
||||||
|
:Return: a CAST object, of the applicable mode.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
|
return _create_cipher(sys.modules[__name__], key, mode, *args, **kwargs)
|
||||||
|
|
||||||
#: Electronic Code Book (ECB). See `Crypto.Cipher._mode_ecb.EcbMode`.
|
|
||||||
MODE_ECB = 1
|
MODE_ECB = 1
|
||||||
#: Cipher-Block Chaining (CBC). See `Crypto.Cipher._mode_cbc.CbcMode`.
|
|
||||||
MODE_CBC = 2
|
MODE_CBC = 2
|
||||||
#: Cipher FeedBack (CFB). See `Crypto.Cipher._mode_cfb.CfbMode`.
|
|
||||||
MODE_CFB = 3
|
MODE_CFB = 3
|
||||||
#: Output FeedBack (OFB). See `Crypto.Cipher._mode_ofb.OfbMode`.
|
|
||||||
MODE_OFB = 5
|
MODE_OFB = 5
|
||||||
#: CounTer Mode (CTR). See `Crypto.Cipher._mode_ctr.CtrMode`.
|
|
||||||
MODE_CTR = 6
|
MODE_CTR = 6
|
||||||
#: OpenPGP Mode. See `Crypto.Cipher._mode_openpgp.OpenPgpMode`.
|
|
||||||
MODE_OPENPGP = 7
|
MODE_OPENPGP = 7
|
||||||
#: EAX Mode. See `Crypto.Cipher._mode_eax.EaxMode`.
|
|
||||||
MODE_EAX = 9
|
MODE_EAX = 9
|
||||||
|
|
||||||
#: Size of a data block (in bytes)
|
# Size of a data block (in bytes)
|
||||||
block_size = 8
|
block_size = 8
|
||||||
#: Size of a key (in bytes)
|
# Size of a key (in bytes)
|
||||||
key_size = xrange(5, 16 + 1)
|
key_size = xrange(5, 16 + 1)
|
||||||
|
|
|
||||||
|
|
@ -20,53 +20,6 @@
|
||||||
# SOFTWARE.
|
# SOFTWARE.
|
||||||
# ===================================================================
|
# ===================================================================
|
||||||
|
|
||||||
"""RSA encryption protocol according to PKCS#1 v1.5
|
|
||||||
|
|
||||||
See RFC3447__ or the `original RSA Labs specification`__ .
|
|
||||||
|
|
||||||
This scheme is more properly called ``RSAES-PKCS1-v1_5``.
|
|
||||||
|
|
||||||
**If you are designing a new protocol, consider using the more robust PKCS#1 OAEP.**
|
|
||||||
|
|
||||||
As an example, a sender may encrypt a message in this way:
|
|
||||||
|
|
||||||
>>> from Crypto.Cipher import PKCS1_v1_5
|
|
||||||
>>> from Crypto.PublicKey import RSA
|
|
||||||
>>> from Crypto.Hash import SHA
|
|
||||||
>>>
|
|
||||||
>>> message = b'To be encrypted'
|
|
||||||
>>> h = SHA.new(message)
|
|
||||||
>>>
|
|
||||||
>>> key = RSA.importKey(open('pubkey.der').read())
|
|
||||||
>>> cipher = PKCS1_v1_5.new(key)
|
|
||||||
>>> ciphertext = cipher.encrypt(message+h.digest())
|
|
||||||
|
|
||||||
At the receiver side, decryption can be done using the private part of
|
|
||||||
the RSA key:
|
|
||||||
|
|
||||||
>>> From Crypto.Hash import SHA
|
|
||||||
>>> from Crypto import Random
|
|
||||||
>>>
|
|
||||||
>>> key = RSA.importKey(open('privkey.der').read())
|
|
||||||
>>>
|
|
||||||
>>> dsize = SHA.digest_size
|
|
||||||
>>> sentinel = Random.new().read(15+dsize) # Let's assume that average data length is 15
|
|
||||||
>>>
|
|
||||||
>>> cipher = PKCS1_v1_5.new(key)
|
|
||||||
>>> message = cipher.decrypt(ciphertext, sentinel)
|
|
||||||
>>>
|
|
||||||
>>> digest = SHA.new(message[:-dsize]).digest()
|
|
||||||
>>> if digest==message[-dsize:]: # Note how we DO NOT look for the sentinel
|
|
||||||
>>> print "Encryption was correct."
|
|
||||||
>>> else:
|
|
||||||
>>> print "Encryption was not correct."
|
|
||||||
|
|
||||||
:undocumented: __revision__, __package__
|
|
||||||
|
|
||||||
.. __: http://www.ietf.org/rfc/rfc3447.txt
|
|
||||||
.. __: http://www.rsa.com/rsalabs/node.asp?id=2125.
|
|
||||||
"""
|
|
||||||
|
|
||||||
__all__ = [ 'new', 'PKCS115_Cipher' ]
|
__all__ = [ 'new', 'PKCS115_Cipher' ]
|
||||||
|
|
||||||
from Crypto.Util.number import ceil_div, bytes_to_long, long_to_bytes
|
from Crypto.Util.number import ceil_div, bytes_to_long, long_to_bytes
|
||||||
|
|
@ -75,7 +28,8 @@ import Crypto.Util.number
|
||||||
from Crypto import Random
|
from Crypto import Random
|
||||||
|
|
||||||
class PKCS115_Cipher:
|
class PKCS115_Cipher:
|
||||||
"""This cipher can perform PKCS#1 v1.5 RSA encryption or decryption."""
|
"""This cipher can perform PKCS#1 v1.5 RSA encryption or decryption.
|
||||||
|
Do not instantiate directly. Use :func:`Crypto.Cipher.PKCS1_v1_5.new` instead."""
|
||||||
|
|
||||||
def __init__(self, key, randfunc):
|
def __init__(self, key, randfunc):
|
||||||
"""Initialize this PKCS#1 v1.5 cipher object.
|
"""Initialize this PKCS#1 v1.5 cipher object.
|
||||||
|
|
@ -102,24 +56,24 @@ class PKCS115_Cipher:
|
||||||
def encrypt(self, message):
|
def encrypt(self, message):
|
||||||
"""Produce the PKCS#1 v1.5 encryption of a message.
|
"""Produce the PKCS#1 v1.5 encryption of a message.
|
||||||
|
|
||||||
This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and is specified in
|
This function is named ``RSAES-PKCS1-V1_5-ENCRYPT``, and it is specified in
|
||||||
section 7.2.1 of RFC3447.
|
`section 7.2.1 of RFC8017
|
||||||
For a complete example see `Crypto.Cipher.PKCS1_v1_5`.
|
<https://tools.ietf.org/html/rfc8017#page-28>`_.
|
||||||
|
|
||||||
:Parameters:
|
:param message:
|
||||||
message : byte string
|
The message to encrypt, also known as plaintext. It can be of
|
||||||
The message to encrypt, also known as plaintext. It can be of
|
variable length, but not longer than the RSA modulus (in bytes) minus 11.
|
||||||
variable length, but not longer than the RSA modulus (in bytes) minus 11.
|
:type message: byte string
|
||||||
|
|
||||||
:Return: A byte string, the ciphertext in which the message is encrypted.
|
:Returns: A byte string, the ciphertext in which the message is encrypted.
|
||||||
It is as long as the RSA modulus (in bytes).
|
It is as long as the RSA modulus (in bytes).
|
||||||
:Raise ValueError:
|
|
||||||
|
:Raises ValueError:
|
||||||
If the RSA key length is not sufficiently long to deal with the given
|
If the RSA key length is not sufficiently long to deal with the given
|
||||||
message.
|
message.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# See 7.2.1 in RFC3447
|
# See 7.2.1 in RFC8017
|
||||||
modBits = Crypto.Util.number.size(self._key.n)
|
modBits = Crypto.Util.number.size(self._key.n)
|
||||||
k = ceil_div(modBits,8) # Convert from bits to bytes
|
k = ceil_div(modBits,8) # Convert from bits to bytes
|
||||||
mLen = len(message)
|
mLen = len(message)
|
||||||
|
|
@ -146,26 +100,30 @@ class PKCS115_Cipher:
|
||||||
c = long_to_bytes(m_int, k)
|
c = long_to_bytes(m_int, k)
|
||||||
return c
|
return c
|
||||||
|
|
||||||
def decrypt(self, ct, sentinel):
|
def decrypt(self, ciphertext, sentinel):
|
||||||
"""Decrypt a PKCS#1 v1.5 ciphertext.
|
"""Decrypt a PKCS#1 v1.5 ciphertext.
|
||||||
|
|
||||||
This function is named ``RSAES-PKCS1-V1_5-DECRYPT``, and is specified in
|
This function is named ``RSAES-PKCS1-V1_5-DECRYPT``, and is specified in
|
||||||
section 7.2.2 of RFC3447.
|
`section 7.2.2 of RFC8017
|
||||||
For a complete example see `Crypto.Cipher.PKCS1_v1_5`.
|
<https://tools.ietf.org/html/rfc8017#page-29>`_.
|
||||||
|
|
||||||
:Parameters:
|
:param ciphertext:
|
||||||
ct : byte string
|
The ciphertext that contains the message to recover.
|
||||||
The ciphertext that contains the message to recover.
|
:type ciphertext: byte string
|
||||||
sentinel : any type
|
|
||||||
The object to return to indicate that an error was detected during decryption.
|
|
||||||
|
|
||||||
:Return: A byte string. It is either the original message or the ``sentinel`` (in case of an error).
|
:param sentinel:
|
||||||
:Raise ValueError:
|
The object to return whenever an error is detected.
|
||||||
|
:type sentinel: any type
|
||||||
|
|
||||||
|
:Returns: A byte string. It is either the original message or the ``sentinel`` (in case of an error).
|
||||||
|
|
||||||
|
:Raises ValueError:
|
||||||
If the ciphertext length is incorrect
|
If the ciphertext length is incorrect
|
||||||
:Raise TypeError:
|
:Raises TypeError:
|
||||||
If the RSA key has no private half.
|
If the RSA key has no private half (i.e. it cannot be used for
|
||||||
|
decyption).
|
||||||
|
|
||||||
:attention:
|
.. warning::
|
||||||
You should **never** let the party who submitted the ciphertext know that
|
You should **never** let the party who submitted the ciphertext know that
|
||||||
this function returned the ``sentinel`` value.
|
this function returned the ``sentinel`` value.
|
||||||
Armed with such knowledge (for a fair amount of carefully crafted but invalid ciphertexts),
|
Armed with such knowledge (for a fair amount of carefully crafted but invalid ciphertexts),
|
||||||
|
|
@ -178,7 +136,7 @@ class PKCS115_Cipher:
|
||||||
|
|
||||||
In fact, the second option is not that unlikely: encryption done according to PKCS#1 v1.5
|
In fact, the second option is not that unlikely: encryption done according to PKCS#1 v1.5
|
||||||
embeds no good integrity check. There is roughly one chance
|
embeds no good integrity check. There is roughly one chance
|
||||||
in 2^16 for a random ciphertext to be returned as a valid message
|
in 2\ :sup:`16` for a random ciphertext to be returned as a valid message
|
||||||
(although random looking).
|
(although random looking).
|
||||||
|
|
||||||
It is therefore advisabled to:
|
It is therefore advisabled to:
|
||||||
|
|
@ -203,10 +161,10 @@ class PKCS115_Cipher:
|
||||||
k = ceil_div(modBits,8) # Convert from bits to bytes
|
k = ceil_div(modBits,8) # Convert from bits to bytes
|
||||||
|
|
||||||
# Step 1
|
# Step 1
|
||||||
if len(ct) != k:
|
if len(ciphertext) != k:
|
||||||
raise ValueError("Ciphertext with incorrect length.")
|
raise ValueError("Ciphertext with incorrect length.")
|
||||||
# Step 2a (O2SIP)
|
# Step 2a (O2SIP)
|
||||||
ct_int = bytes_to_long(ct)
|
ct_int = bytes_to_long(ciphertext)
|
||||||
# Step 2b (RSADP)
|
# Step 2b (RSADP)
|
||||||
m_int = self._key._decrypt(ct_int)
|
m_int = self._key._decrypt(ct_int)
|
||||||
# Complete step 2c (I2OSP)
|
# Complete step 2c (I2OSP)
|
||||||
|
|
@ -218,16 +176,21 @@ class PKCS115_Cipher:
|
||||||
# Step 4
|
# Step 4
|
||||||
return em[sep+1:]
|
return em[sep+1:]
|
||||||
|
|
||||||
def new(key, randfunc=None):
|
|
||||||
"""Return a cipher object `PKCS115_Cipher` that can be used to perform PKCS#1 v1.5 encryption or decryption.
|
|
||||||
|
|
||||||
:Parameters:
|
def new(key, randfunc=None):
|
||||||
key : RSA key object
|
"""Create a cipher for performing PKCS#1 v1.5 encryption or decryption.
|
||||||
|
|
||||||
|
:param key:
|
||||||
The key to use to encrypt or decrypt the message. This is a `Crypto.PublicKey.RSA` object.
|
The key to use to encrypt or decrypt the message. This is a `Crypto.PublicKey.RSA` object.
|
||||||
Decryption is only possible if *key* is a private RSA key.
|
Decryption is only possible if *key* is a private RSA key.
|
||||||
randfunc : callable
|
:type key: RSA key object
|
||||||
|
|
||||||
|
:param randfunc:
|
||||||
Function that return random bytes.
|
Function that return random bytes.
|
||||||
The default is `Crypto.Random.get_random_bytes`.
|
The default is `Crypto.Random.get_random_bytes`.
|
||||||
|
:type randfunc: callable
|
||||||
|
|
||||||
|
:returns: A cipher object `PKCS115_Cipher`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if randfunc is None:
|
if randfunc is None:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue