]> git.datanom.net - securemail.git/blame - cryptonize.py
Make backwards compatible with nacl 1.0.x
[securemail.git] / cryptonize.py
CommitLineData
8c4f590c
MR
1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2018 Michael Rasmussen <mir@datanom.net>
4
5# This file is part of SecureMail.
6
7# SecureMail is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# SecureMail is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with SecureMail. If not, see <https://www.gnu.org/licenses/>.
19
481494d3 20from nacl import __version__ as NACL_VERSION
8c4f590c
MR
21from nacl.secret import SecretBox
22from nacl.public import PrivateKey, Box
d65fab5a 23from nacl.utils import random, EncryptedMessage
8c4f590c
MR
24from nacl.encoding import HexEncoder
25import nacl.hash
26
27class Cryptonize:
28 """
29 Encrypt and decrypt objects
30 """
31
32 def symmetric_encrypt(self, key, plain):
33 skey = self.sanitize_key(key)
34 box = SecretBox(skey)
481494d3 35 if NACL_VERSION < "1.1.0":
481494d3
MR
36 nonce = random(SecretBox.NONCE_SIZE)
37 cipher = box.encrypt(plain, nonce)
38 else:
39 cipher = box.encrypt(plain)
d65fab5a 40 box = skey = None
8c4f590c
MR
41
42 return cipher
43
44 def symmetric_decrypt(self, key, cipher):
45 skey = self.sanitize_key(key)
46 box = SecretBox(skey)
47 plain = box.decrypt(cipher)
d65fab5a 48 box = skey = None
8c4f590c
MR
49
50 return plain
51
52 def asymmetric_encrypt(self, privkey, pubkey, plain):
462ce28c
MR
53 if not isinstance(plain, bytes):
54 plain = plain.encode('utf-8')
8c4f590c 55 box = Box(privkey, pubkey)
3e18b00b
MR
56 if NACL_VERSION < "1.1.0":
57 nonce = random(Box.NONCE_SIZE)
58 cipher = box.encrypt(plain, nonce)
59 else:
60 cipher = box.encrypt(plain)
8c4f590c
MR
61 box = None
62
63 return cipher
64
65 def asymmetric_decrypt(self, privkey, pubkey, cipher):
462ce28c
MR
66 if not isinstance(cipher, bytes):
67 cipher = cipher.encode('utf-8')
8c4f590c
MR
68 box = Box(privkey, pubkey)
69 plain = box.decrypt(cipher)
70 box = None
71
72 return plain
73
74 def get_random_key(self):
75 return random(SecretBox.KEY_SIZE)
76
77 def sanitize_key(self, key):
78 if not isinstance(key, bytes):
79 key = key.encode('utf-8')
80 size = len(key)
81 if size < SecretBox.KEY_SIZE:
d65fab5a
MR
82 """ We must pad """
83 newkey = key + bytes(SecretBox.KEY_SIZE - size)
84 elif size > SecretBox.KEY_SIZE:
85 newkey = key[:SecretBox.KEY_SIZE]
8c4f590c
MR
86 else:
87 newkey = key
88
89
90 return newkey
91
92 def get_key_pair(self):
93 privkey = PrivateKey.generate()
94 pubkey = privkey.public_key
95
96 return (privkey, pubkey)
97
98 def generate_hash(self, key):
99 if not isinstance(key, bytes):
100 key = key.encode('utf-8')
101 HASHER = nacl.hash.sha512
102 digest = HASHER(key, encoder=HexEncoder)
103
104 return digest.decode()
105
d65fab5a
MR
106 def create_EncryptedMessage(self, payload):
107 nonce = payload[:SecretBox.NONCE_SIZE]
108 ciphertext = payload[SecretBox.NONCE_SIZE:]
8c4f590c 109
d65fab5a
MR
110 return EncryptedMessage._from_parts(
111 nonce, ciphertext, nonce + ciphertext)
This page took 0.042561 seconds and 5 git commands to generate.