Switch to Fernet crypto as per gtank's recommendation

This commit is contained in:
Joseph Schorr 2016-01-12 14:08:41 -05:00
parent bd0a098282
commit b4bddacedb
3 changed files with 26 additions and 13 deletions

View file

@ -293,4 +293,4 @@ class DefaultConfig(object):
# "Secret" key for generating encrypted paging tokens. Only needed to be secret to
# hide the ID range for production (in which this value is overridden). Should *not*
# be relied upon for secure encryption otherwise.
PAGE_TOKEN_KEY = 'GdE4<~8&9LHDPM++'
PAGE_TOKEN_KEY = 'um=/?Kqgp)2yQaS/A6C{NL=dXE&>C:}('

View file

@ -22,7 +22,7 @@ from auth.auth import process_oauth
from endpoints.csrf import csrf_protect
from endpoints.decorators import check_anon_protection
from util.saas.metricqueue import time_decorator
from util.security.aes import AESCipher
from util.security.crypto import encrypt_string, decrypt_string
logger = logging.getLogger(__name__)
@ -220,26 +220,21 @@ def page_support(func):
@query_param('next_page', 'The page token for the next page', type=str)
def wrapper(self, query_args, *args, **kwargs):
page_token = None
unecrypted = None
if query_args['next_page']:
# Decrypt the page token.
cipher = AESCipher(app.config['PAGE_TOKEN_KEY'])
try:
unecrypted = cipher.decrypt(query_args['next_page'])
except TypeError:
pass
if unecrypted is not None:
unencrypted = decrypt_string(query_args['next_page'], app.config['PAGE_TOKEN_KEY'])
if unencrypted is not None:
try:
page_token = json.loads(unecrypted)
page_token = json.loads(unencrypted)
except ValueError:
pass
# Note: if page_token is None, we'll receive the first page of results back.
(result, next_page_token) = func(self, query_args, page_token, *args, **kwargs)
if next_page_token is not None:
cipher = AESCipher(app.config['PAGE_TOKEN_KEY'])
result['next_page'] = cipher.encrypt(json.dumps(next_page_token))
result['next_page'] = encrypt_string(json.dumps(next_page_token),
app.config['PAGE_TOKEN_KEY'])
return result

18
util/security/crypto.py Normal file
View file

@ -0,0 +1,18 @@
import base64
from cryptography.fernet import Fernet, InvalidToken
def encrypt_string(string, key):
""" Encrypts a string with the specified key. The key must be 32 raw bytes. """
f = Fernet(base64.urlsafe_b64encode(key))
return f.encrypt(string)
def decrypt_string(string, key):
""" Decrypts an encrypted string with the specified key. The key must be 32 raw bytes. """
f = Fernet(base64.urlsafe_b64encode(key))
try:
return f.decrypt(string)
except InvalidToken:
return None
except TypeError:
return None