OLD | NEW |
(Empty) | |
| 1 # -*- coding: utf-8 -*- |
| 2 # |
| 3 # Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> |
| 4 # |
| 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 # you may not use this file except in compliance with the License. |
| 7 # You may obtain a copy of the License at |
| 8 # |
| 9 # https://www.apache.org/licenses/LICENSE-2.0 |
| 10 # |
| 11 # Unless required by applicable law or agreed to in writing, software |
| 12 # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 # See the License for the specific language governing permissions and |
| 15 # limitations under the License. |
| 16 |
| 17 """Large file support |
| 18 |
| 19 .. deprecated:: 3.4 |
| 20 |
| 21 The VARBLOCK format is NOT recommended for general use, has been deprecated
since |
| 22 Python-RSA 3.4, and will be removed in a future release. It's vulnerable to
a |
| 23 number of attacks: |
| 24 |
| 25 1. decrypt/encrypt_bigfile() does not implement `Authenticated encryption`_
nor |
| 26 uses MACs to verify messages before decrypting public key encrypted messa
ges. |
| 27 |
| 28 2. decrypt/encrypt_bigfile() does not use hybrid encryption (it uses plain R
SA) |
| 29 and has no method for chaining, so block reordering is possible. |
| 30 |
| 31 See `issue #19 on Github`_ for more information. |
| 32 |
| 33 .. _Authenticated encryption: https://en.wikipedia.org/wiki/Authenticated_encryp
tion |
| 34 .. _issue #19 on Github: https://github.com/sybrenstuvel/python-rsa/issues/13 |
| 35 |
| 36 |
| 37 This module contains functions to: |
| 38 |
| 39 - break a file into smaller blocks, and encrypt them, and store the |
| 40 encrypted blocks in another file. |
| 41 |
| 42 - take such an encrypted files, decrypt its blocks, and reconstruct the |
| 43 original file. |
| 44 |
| 45 The encrypted file format is as follows, where || denotes byte concatenation: |
| 46 |
| 47 FILE := VERSION || BLOCK || BLOCK ... |
| 48 |
| 49 BLOCK := LENGTH || DATA |
| 50 |
| 51 LENGTH := varint-encoded length of the subsequent data. Varint comes from |
| 52 Google Protobuf, and encodes an integer into a variable number of bytes. |
| 53 Each byte uses the 7 lowest bits to encode the value. The highest bit set |
| 54 to 1 indicates the next byte is also part of the varint. The last byte will |
| 55 have this bit set to 0. |
| 56 |
| 57 This file format is called the VARBLOCK format, in line with the varint format |
| 58 used to denote the block sizes. |
| 59 |
| 60 """ |
| 61 |
| 62 import warnings |
| 63 |
| 64 from rsa import key, common, pkcs1, varblock |
| 65 from rsa._compat import byte |
| 66 |
| 67 |
| 68 def encrypt_bigfile(infile, outfile, pub_key): |
| 69 """Encrypts a file, writing it to 'outfile' in VARBLOCK format. |
| 70 |
| 71 .. deprecated:: 3.4 |
| 72 This function was deprecated in Python-RSA version 3.4 due to security i
ssues |
| 73 in the VARBLOCK format. See the documentation_ for more information. |
| 74 |
| 75 .. _documentation: https://stuvel.eu/python-rsa-doc/usage.html#working-with-
big-files |
| 76 |
| 77 :param infile: file-like object to read the cleartext from |
| 78 :param outfile: file-like object to write the crypto in VARBLOCK format to |
| 79 :param pub_key: :py:class:`rsa.PublicKey` to encrypt with |
| 80 |
| 81 """ |
| 82 |
| 83 warnings.warn("The 'rsa.bigfile.encrypt_bigfile' function was deprecated in
Python-RSA version " |
| 84 "3.4 due to security issues in the VARBLOCK format. See " |
| 85 "https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-
files " |
| 86 "for more information.", |
| 87 DeprecationWarning, stacklevel=2) |
| 88 |
| 89 if not isinstance(pub_key, key.PublicKey): |
| 90 raise TypeError('Public key required, but got %r' % pub_key) |
| 91 |
| 92 key_bytes = common.bit_size(pub_key.n) // 8 |
| 93 blocksize = key_bytes - 11 # keep space for PKCS#1 padding |
| 94 |
| 95 # Write the version number to the VARBLOCK file |
| 96 outfile.write(byte(varblock.VARBLOCK_VERSION)) |
| 97 |
| 98 # Encrypt and write each block |
| 99 for block in varblock.yield_fixedblocks(infile, blocksize): |
| 100 crypto = pkcs1.encrypt(block, pub_key) |
| 101 |
| 102 varblock.write_varint(outfile, len(crypto)) |
| 103 outfile.write(crypto) |
| 104 |
| 105 |
| 106 def decrypt_bigfile(infile, outfile, priv_key): |
| 107 """Decrypts an encrypted VARBLOCK file, writing it to 'outfile' |
| 108 |
| 109 .. deprecated:: 3.4 |
| 110 This function was deprecated in Python-RSA version 3.4 due to security i
ssues |
| 111 in the VARBLOCK format. See the documentation_ for more information. |
| 112 |
| 113 .. _documentation: https://stuvel.eu/python-rsa-doc/usage.html#working-with-
big-files |
| 114 |
| 115 :param infile: file-like object to read the crypto in VARBLOCK format from |
| 116 :param outfile: file-like object to write the cleartext to |
| 117 :param priv_key: :py:class:`rsa.PrivateKey` to decrypt with |
| 118 |
| 119 """ |
| 120 |
| 121 warnings.warn("The 'rsa.bigfile.decrypt_bigfile' function was deprecated in
Python-RSA version " |
| 122 "3.4 due to security issues in the VARBLOCK format. See " |
| 123 "https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-
files " |
| 124 "for more information.", |
| 125 DeprecationWarning, stacklevel=2) |
| 126 |
| 127 if not isinstance(priv_key, key.PrivateKey): |
| 128 raise TypeError('Private key required, but got %r' % priv_key) |
| 129 |
| 130 for block in varblock.yield_varblocks(infile): |
| 131 cleartext = pkcs1.decrypt(block, priv_key) |
| 132 outfile.write(cleartext) |
| 133 |
| 134 |
| 135 __all__ = ['encrypt_bigfile', 'decrypt_bigfile'] |
OLD | NEW |