def generate_recovery_key(prv_key): rec_key = _GCE.generate_key() pub_key = PrivateKey(prv_key, Base64Encoder).public_key.encode(Base64Encoder) bkp_key = _GCE.symmetric_encrypt(rec_key, prv_key) rec_key = _GCE.asymmetric_encrypt(pub_key, rec_key) return Base64Encoder.encode(bkp_key), Base64Encoder.encode(rec_key)
def validate_password_reset(session, reset_token, auth_code, recovery_key): """ Retrieves a user given a password reset validation token :param session: An ORM session :param reset_token: A reset token :param auth_code: A two factor authentication code (optional) :param recovery_key: An encryption recovery key (optional) :return: A descriptor describing the result of the operation """ now = datetime.now() prv_key = '' user = session.query(models.User).filter( models.User.reset_password_token == reset_token, models.User.reset_password_date >= now - timedelta(hours=72) ).one_or_none() # If the authentication token is invalid if user is None: return {'status': 'invalid_reset_token_provided'} # If encryption is enabled require the recovery key if user.crypto_prv_key: try: x = State.TempKeys.pop(user.id, None) if x: enc_key = GCE.derive_key(reset_token.encode(), user.salt) prv_key = GCE.symmetric_decrypt(enc_key, Base64Encoder.decode(x.key)) else: recovery_key = recovery_key.replace('-', '').upper() + '====' recovery_key = Base32Encoder.decode(recovery_key.encode()) prv_key = GCE.symmetric_decrypt(recovery_key, Base64Encoder.decode(user.crypto_bkp_key)) except: return {'status': 'require_recovery_key'} elif user.two_factor_enable: two_factor_secret = user.two_factor_secret if not pyotp.TOTP(two_factor_secret).verify(auth_code, valid_window=1): return {'status': 'require_two_factor_authentication'} # Token is used, void it out user.reset_password_token = None user.reset_password_date = now # Require password change user.password_change_needed = True session = Sessions.new(user.tid, user.id, user.tid, user.role, user.password_change_needed, user.two_factor_enable, prv_key, user.crypto_escrow_prv_key) return {'status': 'success', 'token': session.id}
def handle(self, *args, **options): """Handle the command""" private_key = PrivateKey.generate() public_key = private_key.public_key self.stdout.write('--------------------------------------------------------------') self.stdout.write('Private Key Base64 Encoded:') self.stdout.write(Base64Encoder.encode(bytes(private_key)).decode("utf-8")) self.stdout.write('--------------------------------------------------------------') self.stdout.write('Public Key Base64 Encoded:') self.stdout.write(Base64Encoder.encode(bytes(public_key)).decode("utf-8")) self.stdout.write('--------------------------------------------------------------')
def test_base64_smessage_with_detached_sig_matches_with_attached_sig(self): sk = SigningKey.generate() vk = sk.verify_key smsg = sk.sign(b"Hello World in base64", encoder=Base64Encoder) msg = smsg.message b64sig = smsg.signature sig = Base64Encoder.decode(b64sig) assert vk.verify(msg, sig, encoder=Base64Encoder) == \ vk.verify(smsg, encoder=Base64Encoder) assert Base64Encoder.decode(msg) == b"Hello World in base64"
def read_file(file_name, base64=False): f = open(file_name, 'r') data = f.read() if base64: data = Base64Encoder.decode(data) f.close() return data
def verify_signature(webhook_uri, signature_header, signature_expiry_seconds=60): # v1 is signature, s is submissionId, f is formId, t is submission epoch logger.debug(f'X-FormSG-Signature is <{signature_header}>.') formsg_signature = dict( part.split('=', 1) for part in signature_header.split(',')) formsg_signature['t'] = int(formsg_signature['t']) # Javascript url.href adds a trailing `/` to root domain urls # https://github.com/opengovsg/formsg-javascript-sdk/blob/master/src/webhooks.ts#L25 u = urlparse(webhook_uri) if not u.path: u = u._replace(path='/') webhook_uri = u.geturl() FORMSG_WEBHOOK_PUBLIC_KEY.verify( smessage= f'{webhook_uri}.{formsg_signature["s"]}.{formsg_signature["f"]}.{formsg_signature["t"]}' .encode('ascii'), signature=Base64Encoder.decode(formsg_signature['v1']), ) if time() - (formsg_signature['t'] / 1000) > signature_expiry_seconds: raise BadSignatureError('FormSG signature has expired.') return formsg_signature
def handle(self, *args, **options): """Handle the command""" private_key = PrivateKey.generate() public_key = private_key.public_key self.stdout.write( '--------------------------------------------------------------') self.stdout.write('Private Key Base64 Encoded:') self.stdout.write( Base64Encoder.encode(bytes(private_key)).decode("utf-8")) self.stdout.write( '--------------------------------------------------------------') self.stdout.write('Public Key Base64 Encoded:') self.stdout.write( Base64Encoder.encode(bytes(public_key)).decode("utf-8")) self.stdout.write( '--------------------------------------------------------------')
def _read_bytes_as_b64_from_file(self, file_path, silent=False): try: with open(file_path, 'r') as read_file: return Base64Encoder.decode(read_file.read()) except Exception as e: if not silent: print(f'Opening file: {file_path}') print(e.args[1])
def set_user_password(tid, user, password, cc): # Regenerate the password hash only if different from the best choice on the platform if user.hash_alg != 'ARGON2': user.hash_alg = 'ARGON2' user.salt = GCE.generate_salt() password_hash = GCE.hash_password(password, user.salt) # Check that the new password is different form the current password if user.password == password_hash: raise errors.PasswordReuseError user.password = password_hash user.password_change_date = datetime_now() State.log(tid=tid, type='change_password', user_id=user.id, object_id=user.id) if not State.tenant_cache[tid].encryption and cc == '': return None enc_key = GCE.derive_key(password.encode(), user.salt) if not cc: # The first password change triggers the generation # of the user encryption private key and its backup cc, user.crypto_pub_key = GCE.generate_keypair() user.crypto_bkp_key, user.crypto_rec_key = GCE.generate_recovery_key( cc) user.crypto_prv_key = Base64Encoder.encode( GCE.symmetric_encrypt(enc_key, cc)) if State.tenant_cache[1].crypto_escrow_pub_key: user.crypto_escrow_bkp1_key = Base64Encoder.encode( GCE.asymmetric_encrypt(State.tenant_cache[1].crypto_escrow_pub_key, cc)) if State.tenant_cache[tid].crypto_escrow_pub_key: user.crypto_escrow_bkp2_key = Base64Encoder.encode( GCE.asymmetric_encrypt( State.tenant_cache[tid].crypto_escrow_pub_key, cc)) return cc
def decrypt(self, encrypted, sender_pub, recipient): box = Box(secret_key(recipient), public_key(sender_pub)) if encrypted[:4] != 'msg:': raise DecryptionError try: return box.decrypt(Base64Encoder.decode(encrypted[4:])) except CryptoError: raise DecryptionError
def Decrypt_NaCl(Pk, Sk, nonce, ciphertext): Sk = PrivateKeyNaCl(Sk, encoder=Base64Encoder) Pk = PublicKeyNaCl(Pk, encoder=Base64Encoder) nonce = Base64Encoder.decode(nonce) box = BoxNaCl(Sk, Pk) # import numpy as np # print np.fromstring(box.shared_key(), dtype=np.uint8) plaintext = box.decrypt(ciphertext, nonce, encoder=Base64Encoder) return plaintext
def _decrypt_and_set_private_key(self, private_key_store): if not self.password: raise AttributeError( 'No password found! Password must be set ahead!') secure_key = pwhash.argon2i.kdf(secret.SecretBox.KEY_SIZE, Base64Encoder.decode(self.password), Base64Encoder.decode( private_key_store['salt']), opslimit=private_key_store['ops'], memlimit=private_key_store['mem']) encrypted = Base64Encoder.decode(private_key_store['private_key']) box = secret.SecretBox(secure_key) try: self.private_key = PrivateKey(box.decrypt(encrypted)) self.public_key = self.private_key.public_key return True except Exception as e: print(e)
def invalid_settings(): """ Fixture that runs a test against a set of invalid configurations """ settings = copy.copy(DEFAULT_SETTINGS) settings.update({ 'EXAMS_AUDIT_NACL_PUBLIC_KEY': Base64Encoder.encode('bad'), }) with override_settings(**settings): yield settings
def valid_settings(private_key): """ Fixture that provides valid (passes checks in configure()) configuration """ settings = copy.copy(DEFAULT_SETTINGS) settings.update({ 'EXAMS_AUDIT_NACL_PUBLIC_KEY': Base64Encoder.encode(bytes(private_key.public_key)), }) with override_settings(**settings): yield DEFAULT_SETTINGS
def decrypt_text(self, cipher_text): if not self.private_key: self.import_private_key_from_file() if not self.private_key: raise AttributeError( 'No private key known or found in file. Generate private key first!' ) else: unseal_box = SealedBox(self.private_key) if re.fullmatch(self.CIPHER_PATTERN, cipher_text): cipher_text = re.search(self.CIPHER_PATTERN, cipher_text).group(1) return unseal_box.decrypt( Base64Encoder.decode(cipher_text)).decode('utf-8')
def get_auth(user_id, name, secret, nonce, method, uri, body=None): if body is not None: if not isinstance(body, str): try: body = json.dumps(body, separators=(',', ':')) except ValueError as e: logger.exception( 'invalid body. json or string are valid body type') request_string = '{"method":"' + method + '","uri":"' + uri + ('",' if ( body is None) else '","body":' + body + ',') + '"nonce":' + nonce + '}' logger.debug("message %s", request_string) raw_signed = crypto_sign(request_string.encode(), bytes.fromhex(secret)) signature = Base64Encoder.encode(raw_signed[:crypto_sign_BYTES]) return 'SIGN ' + user_id + "." + name + ':' + signature.decode()
def get_recovery_key(session, tid, user_id, user_cc): """ Transaction to get a user recovery key :param session: An ORM session :param tid: The tenant ID :param user_id: The user ID :param user_cc: The user key :return: The recovery key encoded base32 """ user = db_get_user(session, tid, user_id) if not user.crypto_rec_key: return '' user.clicked_recovery_key = True return Base32Encoder.encode(GCE.asymmetric_decrypt(user_cc, Base64Encoder.decode(user.crypto_rec_key.encode()))).replace(b'=', b'')
def get_cybersource_test_settings(private_key=None): """ Generates a valid set of settings for CyberSource """ if private_key is None: private_key = PrivateKey.generate() return { "CYBERSOURCE_WSDL_URL": (f"http://localhost/service/CyberSourceTransaction_{SERVICE_VERSION}.wsdl" ), "CYBERSOURCE_MERCHANT_ID": "merchant_id", "CYBERSOURCE_TRANSACTION_KEY": "transaction_key", "CYBERSOURCE_INQUIRY_LOG_NACL_ENCRYPTION_KEY": Base64Encoder.encode(bytes(private_key.public_key)), }
def decrypt_content(body_json, secret_key): if 'data' in body_json: encrypted_content = body_json['data']['encryptedContent'] else: encrypted_content = body_json[ 'encryptedContent'] # old version POST body #end if submission_public_key, nonce, encrypted_message = ENCRYPTED_CONTENT_REGEX.match( encrypted_content).groups() box = Box( PrivateKey(secret_key, encoder=Base64Encoder), PublicKey(submission_public_key, encoder=Base64Encoder), ) plaintext = box.decrypt(encrypted_message, Base64Encoder.decode(nonce), encoder=Base64Encoder) return json.loads(plaintext)
def export_private_key_to_file(self): if not self.private_key: raise AttributeError( 'No private key found to export. Generate or set private key first!' ) else: salt = utils.random(pwhash.argon2i.SALTBYTES) secure_key = pwhash.argon2i.kdf(secret.SecretBox.KEY_SIZE, Base64Encoder.decode( self.password), salt, opslimit=self.ops, memlimit=self.mem) private_key_store = { 'private_key': self._encrypt_private_key(secure_key), 'salt': self._base64(salt), 'ops': self.ops, 'mem': self.mem } return self._write_dict_as_json_file(private_key_store, self.private_key_store)
def b2a(b): return Base64Encoder.encode(b)
def _base64(self, data: bytes): return Base64Encoder.encode(data).decode('ASCII')
def fax_status_callback(request: HttpRequest): # get relevant signature data event_timestamp = request.headers.get("Telnyx-Timestamp") event_signature = request.headers.get("Telnyx-Signature-Ed25519") public_key = settings.TELNYX_PUBLIC_KEY # prepare signature data for nacl verify_key = VerifyKey(public_key, encoder=Base64Encoder) callback_bytes = f"{event_timestamp}|".encode("UTF-8") + request.body signature = Base64Encoder.decode(event_signature) # verify signature try: verify_key.verify(callback_bytes, signature=signature) except BadSignatureError: return HttpResponseForbidden("invalid signature", content_type="text/plain") payload_json = json.loads(request.body) # get message object fax_id = None try: fax_id = payload_json.get("data").get("payload").get("fax_id") except AttributeError as e: # this key should always exist. we should never end up here raise ValueError( f"This is not a valid API response body: {request.body}") from e if not fax_id: raise ValueError( f"This is not a valid API response body: {request.body}") fax_message: FoiMessage = get_object_or_404(FoiMessage, email_message_id=fax_id) # find status try: status = payload_json.get("data").get("payload").get("status") except AttributeError as e: # we should never end up here either raise ValueError( f"This is not a valid API response body: {request.body}") from e if status == "failed": status = DeliveryStatus.Delivery.STATUS_FAILED elif status == "queued": status = DeliveryStatus.Delivery.STATUS_SENDING elif status == "media.processed": status = DeliveryStatus.Delivery.STATUS_SENDING elif status.startswith("sending"): status = DeliveryStatus.Delivery.STATUS_SENDING elif status == "delivered": status = DeliveryStatus.Delivery.STATUS_SENT else: # again: we should not end up here. according to telnyx-docu those are all possible stati raise ValueError(f"This is not a valid status response: {status}") # only try and update if the timestamp in request is more recent than the one in the database dt = datetime.datetime.fromtimestamp(int(event_timestamp), pytz.timezone("UTC")) if fax_message.deliverystatus.last_update > dt: return HttpResponse(status=409) ds, _created = DeliveryStatus.objects.update_or_create( message=fax_message, defaults=dict( status=status, last_update=timezone.now(), ), ) data = payload_json.get("data") # Create machine-readable log fax_log_data = { "from_": data["payload"]["from"], "to": data["payload"]["to"], "sid": data["payload"]["fax_id"], "status": data["payload"]["status"], "num_pages": data["payload"].get("page_count", 0), "duration": data["payload"].get("call_duration_secs", 0), "failure_reason": data["payload"].get("failure_reason"), "date_created": data["occurred_at"], } ds.log = create_fax_log(ds.log, fax_log_data) ds.save() if status == DeliveryStatus.Delivery.STATUS_SENT: fax_message.timestamp = ds.last_update fax_message.save() ProblemReport.objects.find_and_resolve( message=fax_message, kind=ProblemReport.PROBLEM.BOUNCE_PUBLICBODY) failed = False if status == DeliveryStatus.Delivery.STATUS_FAILED: if ds.retry_count >= 3: failed = True else: # Retry fax delivery in 15 minutes retry_fax_delivery.apply_async( (fax_message.pk, ), {}, # resend in intervals of 0.25, 1, 2 and 4 hours countdown=15 * 60 * 4**ds.retry_count, ) if failed: ProblemReport.objects.report( message=fax_message, kind=ProblemReport.PROBLEM.BOUNCE_PUBLICBODY, description=ds.log, auto_submitted=True, ) return HttpResponse(status=200)
def set_public_key(self, b64_public_key): self.public_key = PublicKey(Base64Encoder.decode(b64_public_key))
################################################################################ # BEGIN MOCKS NECESSARY FOR DETERMINISTIC ENCRYPTION VALID_PASSWORD1 = 'ACollectionOfDiplomaticHistorySince_1966_ToThe_Pr esentDay#' VALID_PASSWORD2 = VALID_PASSWORD1 VALID_SALT1 = GCE.generate_salt() VALID_SALT2 = GCE.generate_salt() VALID_HASH1 = GCE.hash_password(VALID_PASSWORD1, VALID_SALT1) VALID_HASH2 = GCE.hash_password(VALID_PASSWORD2, VALID_SALT2) VALID_BASE64_IMG = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVQYV2NgYAAAAAMAAWgmWQ0AAAAASUVORK5CYII=' INVALID_PASSWORD = '******' KEY = GCE.generate_key() USER_KEY = GCE.derive_key(VALID_PASSWORD1, VALID_SALT1) USER_PRV_KEY, USER_PUB_KEY = GCE.generate_keypair() USER_PRV_KEY_ENC = Base64Encoder.encode( GCE.symmetric_encrypt(USER_KEY, USER_PRV_KEY)) USER_BKP_KEY, USER_REC_KEY = GCE.generate_recovery_key(USER_PRV_KEY) USER_REC_KEY_PLAIN = GCE.asymmetric_decrypt(USER_PRV_KEY, Base64Encoder.decode(USER_REC_KEY)) USER_REC_KEY_PLAIN = Base32Encoder.encode(USER_REC_KEY_PLAIN).replace( b'=', b'').decode('utf-8') GCE_orig_generate_key = GCE.generate_key GCE_orig_generate_keypair = GCE.generate_keypair def mock_nullfunction(*args, **kwargs): return def mock_GCE_generate_key(): return KEY
message = 'abcdefg1234' encoding = 'utf-8' print('-' * 100) print('KEY and MESSAGE') print('-' * 100) print('PRIKEY:', prikey) print('PRIKEY(BASE64):', prikey.encode(Base64Encoder).decode(encoding)) print('PUBKEY:', pubkey) print('PUBKEY(BASE64):', pubkey.encode(Base64Encoder).decode(encoding)) print('MESSAGE:', message) print('-' * 100) print('ENCRYPT with public key') print('-' * 100) box = SealedBox(pubkey) encrypted = box.encrypt(message.encode(encoding=encoding)) print('ENCRYPTED MESSAGE:', encrypted) print('ENCRYPTED MESSAGE(BASE64):', Base64Encoder.encode(encrypted).decode(encoding)) print('-' * 100) print('DECRYPT with private key') print('-' * 100) box = SealedBox(prikey) decrypted = box.decrypt(encrypted).decode(encoding=encoding) print('DECRYPTED MESSAGE:', decrypted)
def a2b(a): return Base64Encoder.decode(a)
def challenge(self): return Base64Encoder.encode(self.nonce())
def write_file(file_name, data, base64=False): if base64: data = Base64Encoder.encode(data).decode('ascii') f = open(file_name, 'w') f.write(data) f.close()