11 |
11 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12 |
12 |
# GNU Affero General Public License for more details.
|
13 |
13 |
#
|
14 |
14 |
# You should have received a copy of the GNU Affero General Public License
|
15 |
15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16 |
16 |
|
17 |
17 |
import binascii
|
18 |
18 |
|
19 |
|
from Crypto.Cipher import AES
|
20 |
|
from Crypto.Protocol.KDF import PBKDF2
|
21 |
|
from Crypto import Random
|
|
19 |
from Cryptodome.Cipher import AES
|
|
20 |
from Cryptodome.Protocol.KDF import PBKDF2
|
|
21 |
from Cryptodome import Random
|
22 |
22 |
|
23 |
23 |
from django.utils import six
|
24 |
|
from django.utils.encoding import force_text
|
|
24 |
from django.utils.encoding import force_bytes, force_text
|
25 |
25 |
|
26 |
26 |
|
27 |
27 |
class DecryptionError(Exception):
|
28 |
28 |
pass
|
29 |
29 |
|
30 |
30 |
|
31 |
31 |
def aes_hex_encrypt(key, data):
|
32 |
32 |
'''Generate an AES key from any key material using PBKDF2, and encrypt data using CFB mode. A
|
33 |
33 |
new IV is generated each time, the IV is also used as salt for PBKDF2.
|
34 |
34 |
'''
|
35 |
35 |
iv = Random.get_random_bytes(2) * 8
|
36 |
36 |
aes_key = PBKDF2(key, iv)
|
37 |
37 |
aes = AES.new(aes_key, AES.MODE_CFB, iv)
|
38 |
|
crypted = aes.encrypt(data)
|
|
38 |
crypted = aes.encrypt(force_bytes(data))
|
39 |
39 |
return force_text(b'%s%s' % (binascii.hexlify(iv[:2]), binascii.hexlify(crypted)))
|
40 |
40 |
|
41 |
41 |
def aes_hex_decrypt(key, payload, raise_on_error=True):
|
42 |
42 |
'''Decrypt data encrypted with aes_base64_encrypt'''
|
43 |
43 |
try:
|
44 |
44 |
iv, crypted = payload[:4], payload[4:]
|
45 |
45 |
except (ValueError, TypeError):
|
46 |
46 |
if raise_on_error:
|