Skip to content

Commit 1ae39f2

Browse files
committed
Added new Encrypted column type for AES256 encrypted columns
1 parent 2be4e41 commit 1ae39f2

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

pyproject.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "sqlorm-py"
3-
version = "0.2.1"
3+
version = "0.2.2"
44
description = "A new kind or ORM that do not abstract away your database or SQL queries."
55
authors = ["Maxime Bouroumeau-Fuseau <[email protected]>"]
66
readme = "README.md"
@@ -13,6 +13,7 @@ python = "^3.10"
1313
blinker = "^1.8.2"
1414
psycopg = { extras = ["binary"], version = "^3.1.18", optional = true }
1515
mysql-connector-python = { version = "^8.3.0", optional = true }
16+
pycryptodome = { version = "^3.20.0", optional = true }
1617

1718
[tool.poetry.group.dev.dependencies]
1819
pytest = "^8.0.0"

sqlorm/types.py renamed to sqlorm/types/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ def __str__(self):
5757
}
5858
)
5959

60+
from .encrypted import Encrypted
61+
6062
__all__ = (
6163
"SQLType",
6264
"Integer",
@@ -68,4 +70,5 @@ def __str__(self):
6870
"DateTime",
6971
"JSON",
7072
"Pickle",
73+
"Encrypted"
7174
)

sqlorm/types/encrypted.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import base64
2+
from Crypto.Cipher import AES
3+
from Crypto import Random
4+
import os
5+
from . import SQLType
6+
7+
8+
class Encrypted(SQLType):
9+
block_size = 16
10+
11+
def __init__(self, key):
12+
super().__init__("text", self.decrypt, self.encrypt)
13+
self.key = key
14+
15+
def encrypt(self, raw):
16+
raw = self.pad(raw).encode()
17+
iv = Random.new().read(AES.block_size)
18+
key = self.key() if callable(self.key) else self.key
19+
cipher = AES.new(key, AES.MODE_CBC, iv)
20+
return base64.b64encode(iv + cipher.encrypt(raw))
21+
22+
def decrypt(self, enc):
23+
enc = base64.b64decode(enc)
24+
iv = enc[:16]
25+
key = self.key() if callable(self.key) else self.key
26+
cipher = AES.new(key, AES.MODE_CBC, iv)
27+
return self.unpad(cipher.decrypt(enc[16:]).decode())
28+
29+
def pad(self, s):
30+
return s + (self.block_size - len(s) % self.block_size) * chr(self.block_size - len(s) % self.block_size)
31+
32+
def unpad(self, s):
33+
return s[:-ord(s[len(s)-1:])]

0 commit comments

Comments
 (0)