|
7 | 7 | BLOCK_SIZE = AES.block_size # Bytes
|
8 | 8 | pad = lambda s: s + ((BLOCK_SIZE - len(s) % BLOCK_SIZE) *
|
9 | 9 | chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)).encode('utf-8')
|
| 10 | + |
| 11 | + |
10 | 12 | unpad = lambda s: s[:-ord(s[len(s) - 1:])]
|
11 | 13 |
|
12 | 14 | salt = unhexlify("3fb8877d37fdc04e4a4765EFb8ab7d36")
|
13 | 15 |
|
| 16 | +class PaddingError(Exception): |
| 17 | + """Exception raised for errors in the padding. |
| 18 | +
|
| 19 | + Attributes: |
| 20 | + message -- explanation of the error |
| 21 | + """ |
| 22 | + |
| 23 | + def __init__(self, message): |
| 24 | + self.message = message |
| 25 | + |
| 26 | + |
| 27 | +def unpad(s): |
| 28 | + inLen = len(s) |
| 29 | + if inLen == 0: |
| 30 | + raise PaddingError("empty input") |
| 31 | + padChar = s[-1] |
| 32 | + padLen = ord(s[inLen-1:]) |
| 33 | + if padLen > BLOCK_SIZE: |
| 34 | + raise PaddingError("padding length > 16") |
| 35 | + for i in s[inLen-padLen:]: |
| 36 | + if i != padChar: |
| 37 | + raise PaddingError("unknown padding char") |
| 38 | + return s[:-padLen] |
| 39 | + |
14 | 40 |
|
15 | 41 | # kdf does 2 times sha256 and takes the first 16 bytes
|
16 | 42 | def kdf(raw_key):
|
17 |
| - return hashlib.sha256(hashlib.sha256(raw_key.encode('utf-8') + salt).digest()).digest()[:16] |
| 43 | + return hashlib.sha256(hashlib.sha256(raw_key + salt).digest()).digest()[:16] |
18 | 44 |
|
19 | 45 |
|
20 | 46 | def encrypt(raw, password):
|
| 47 | + """ |
| 48 | + encrypt encrypts data with given password by AES-128-CBC PKCS#7, iv will be placed |
| 49 | + at head of cipher data. |
| 50 | +
|
| 51 | + :param raw: input raw byte array |
| 52 | + :param password: password byte array |
| 53 | + :return: encrypted byte array |
| 54 | + """ |
21 | 55 | iv = Random.new().read(AES.block_size)
|
22 | 56 | cipher = AES.new(kdf(password), AES.MODE_CBC, iv)
|
23 | 57 | return iv + cipher.encrypt(pad(raw))
|
24 | 58 |
|
25 | 59 |
|
26 | 60 | def decrypt(enc, password):
|
| 61 | + """ |
| 62 | + decrypt decrypts data with given password by AES-128-CBC PKCS#7. iv will be read from |
| 63 | + the head of raw. |
| 64 | +
|
| 65 | + :param enc: input encrypted byte array |
| 66 | + :param password: password byte array |
| 67 | + :return: decrypted byte array |
| 68 | + """ |
27 | 69 | iv = enc[:16]
|
28 | 70 | cipher = AES.new(kdf(password), AES.MODE_CBC, iv)
|
29 | 71 | return unpad(cipher.decrypt(enc[16:]))
|
0 commit comments