Skip to content

Commit 1af02e2

Browse files
committed
server: tweak token generation to add checksum
1 parent 91e5529 commit 1af02e2

File tree

2 files changed

+27
-7
lines changed

2 files changed

+27
-7
lines changed

server/polar/kit/crypto.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,46 @@
11
import hashlib
22
import hmac
33
import secrets
4+
import string
5+
import zlib
6+
7+
8+
def _crc32_to_base62(number: int) -> str:
9+
characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
10+
base = len(characters)
11+
encoded = ""
12+
while number:
13+
number, remainder = divmod(number, base)
14+
encoded = characters[remainder] + encoded
15+
return encoded.zfill(6) # Ensure the checksum is 6 characters long
416

517

618
def get_token_hash(token: str, *, secret: str) -> str:
719
hash = hmac.new(secret.encode("ascii"), token.encode("ascii"), hashlib.sha256)
820
return hash.hexdigest()
921

1022

11-
def generate_token(*, prefix: str = "", nbytes: int | None = None) -> str:
12-
return f"{prefix}{secrets.token_urlsafe(nbytes)}"
23+
def generate_token(*, prefix: str = "") -> str:
24+
# Generate a high entropy random token
25+
token = "".join(
26+
secrets.choice(string.ascii_letters + string.digits) for _ in range(37)
27+
)
28+
29+
# Calculate a 32-bit CRC checksum
30+
checksum = zlib.crc32(token.encode("utf-8")) & 0xFFFFFFFF
31+
checksum_base62 = _crc32_to_base62(checksum)
32+
33+
# Concatenate the prefix, token, and checksum
34+
return f"{prefix}{token}{checksum_base62}"
1335

1436

15-
def generate_token_hash_pair(
16-
*, secret: str, prefix: str = "", nbytes: int | None = None
17-
) -> tuple[str, str]:
37+
def generate_token_hash_pair(*, secret: str, prefix: str = "") -> tuple[str, str]:
1838
"""
1939
Generate a token suitable for sensitive values
2040
like magic link tokens.
2141
2242
Returns both the actual value and its HMAC-SHA256 hash.
2343
Only the latter shall be stored in database.
2444
"""
25-
token = generate_token(prefix=prefix, nbytes=nbytes)
45+
token = generate_token(prefix=prefix)
2646
return token, get_token_hash(token, secret=secret)

server/polar/oauth2/authorization_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def generate_client_registration_info(
7070
}
7171

7272
def generate_client_id(self) -> str:
73-
return generate_token(prefix=CLIENT_ID_PREFIX, nbytes=16)
73+
return generate_token(prefix=CLIENT_ID_PREFIX)
7474

7575
def generate_client_secret(self) -> str:
7676
return generate_token(prefix=CLIENT_SECRET_PREFIX)

0 commit comments

Comments
 (0)