boxcla: Verified that @jmoldow has signed the CLA. Thanks for the pull request!
Jeff-Meadows: 👍 
diff --git a/HISTORY.rst b/HISTORY.rst
index e7ca71f..25def3f 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -6,7 +6,12 @@ Release History
 Upcoming
 ++++++++
 
-1.5.2
+1.5.3
+++++++++++++++++++
+
+- Bugfix so that ``JWTAuth`` opens the PEM private key file in ``'rb'`` mode.
+
+1.5.2 (2016-05-19)
 ++++++++++++++++++
 
 - Bugfix so that ``OAuth2`` always has the correct tokens after a call to ``refresh()``.
diff --git a/boxsdk/auth/jwt_auth.py b/boxsdk/auth/jwt_auth.py
index 2d81697..266fff2 100644
--- a/boxsdk/auth/jwt_auth.py
+++ b/boxsdk/auth/jwt_auth.py
@@ -1,6 +1,6 @@
 # coding: utf-8
 
-from __future__ import unicode_literals
+from __future__ import absolute_import, unicode_literals
 
 from datetime import datetime, timedelta
 import random
@@ -95,7 +95,7 @@ def __init__(
             refresh_token=None,
             network_layer=network_layer,
         )
-        with open(rsa_private_key_file_sys_path) as key_file:
+        with open(rsa_private_key_file_sys_path, 'rb') as key_file:
             self._rsa_private_key = serialization.load_pem_private_key(
                 key_file.read(),
                 password=rsa_private_key_passphrase,
@@ -182,6 +182,7 @@ def authenticate_instance(self):
         :rtype:
             `unicode`
         """
+        self._user_id = None
         return self._auth_with_jwt(self._enterprise_id, 'enterprise')
 
     def _refresh(self, access_token):
diff --git a/boxsdk/version.py b/boxsdk/version.py
index 9f6ca5f..e4cd37c 100644
--- a/boxsdk/version.py
+++ b/boxsdk/version.py
@@ -3,4 +3,4 @@
 from __future__ import unicode_literals, absolute_import
 
 
-__version__ = '1.5.2'
+__version__ = '1.5.3'

Private key file throws error when trying load_pem_private_key
I'm running python-3.5.0 on OS X 10.11.5. When trying to use JWT Authorization, creating a JWTAuth object fails with:

```
Traceback (most recent call last):
  File "<stdin>", line 6, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/boxsdk/auth/jwt_auth.py", line 102, in __init__
    backend=default_backend(),
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/cryptography/hazmat/primitives/serialization.py", line 20, in load_pem_private_key
    return backend.load_pem_private_key(data, password)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/cryptography/hazmat/backends/multibackend.py", line 289, in load_pem_private_key
    return b.load_pem_private_key(data, password)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1069, in load_pem_private_key
    password,
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 1247, in _load_key
    mem_bio = self._bytes_to_bio(data)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages/cryptography/hazmat/backends/openssl/backend.py", line 477, in _bytes_to_bio
    data_char_p = self._ffi.new("char[]", data)
TypeError: initializer for ctype 'char[]' must be a bytes or list or tuple, not str
```

The default `openssl` backend is what seems to be the problem, but I'm not sure if I'm missing a step. [This issue](https://github.com/pyca/pyopenssl/issues/15) suggests that this is an expected result.

I have tried a workaround that seems to work, but there are some issues there, as well.
diff --git a/test/unit/auth/test_jwt_auth.py b/test/unit/auth/test_jwt_auth.py
index a117850..c65af57 100644
--- a/test/unit/auth/test_jwt_auth.py
+++ b/test/unit/auth/test_jwt_auth.py
@@ -73,7 +73,7 @@ def jwt_auth_init_mocks(
     }
 
     mock_network_layer.request.return_value = successful_token_response
-    key_file_read_data = 'key_file_read_data'
+    key_file_read_data = b'key_file_read_data'
     with patch('boxsdk.auth.jwt_auth.open', mock_open(read_data=key_file_read_data), create=True) as jwt_auth_open:
         with patch('cryptography.hazmat.primitives.serialization.load_pem_private_key') as load_pem_private_key:
             oauth = JWTAuth(
@@ -88,7 +88,7 @@ def jwt_auth_init_mocks(
                 jwt_key_id=jwt_key_id,
             )
 
-            jwt_auth_open.assert_called_once_with(sentinel.rsa_path)
+            jwt_auth_open.assert_called_once_with(sentinel.rsa_path, 'rb')
             jwt_auth_open.return_value.read.assert_called_once_with()  # pylint:disable=no-member
             load_pem_private_key.assert_called_once_with(
                 key_file_read_data,

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-xdist mock sqlalchemy bottle
apt-get update apt-get install -y gcc
3.5
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
async-timeout==4.0.2
attrs==22.2.0
bottle==0.13.2
-e git+https://github.com/box/box-python-sdk.git@481a86227d6d063f2e4e4ae880f4e12cd16dab06#egg=boxsdk
certifi==2021.5.30
cffi==1.15.1
charset-normalizer==2.0.12
cryptography==40.0.2
execnet==1.9.0
greenlet==2.0.2
idna==3.10
importlib-metadata==4.8.3
iniconfig==1.1.1
mock==5.2.0
packaging==21.3
pluggy==1.0.0
py==1.11.0
pycparser==2.21
PyJWT==2.4.0
pyparsing==3.1.4
pytest==7.0.1
pytest-xdist==3.0.2
redis==4.3.6
requests==2.27.1
requests-toolbelt==1.0.0
six==1.17.0
SQLAlchemy==1.4.54
tomli==1.2.3
typing_extensions==4.1.1
urllib3==1.26.20
zipp==3.6.0

name: box-python-sdk
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - async-timeout==4.0.2
      - attrs==22.2.0
      - bottle==0.13.2
      - cffi==1.15.1
      - charset-normalizer==2.0.12
      - cryptography==40.0.2
      - execnet==1.9.0
      - greenlet==2.0.2
      - idna==3.10
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - mock==5.2.0
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pycparser==2.21
      - pyjwt==2.4.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-xdist==3.0.2
      - redis==4.3.6
      - requests==2.27.1
      - requests-toolbelt==1.0.0
      - six==1.17.0
      - sqlalchemy==1.4.54
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - zipp==3.6.0
prefix: /opt/conda/envs/box-python-sdk

test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[16-RS256-None] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[16-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[16-RS512-None] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[16-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[32-RS256-None] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[32-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[32-RS512-None] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[32-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[128-RS256-None] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[128-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[128-RS512-None] test/unit/auth/test_jwt_auth.py::test_authenticate_app_user_sends_post_request_with_correct_params[128-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[16-RS256-None] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[16-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[16-RS512-None] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[16-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[32-RS256-None] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[32-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[32-RS512-None] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[32-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[128-RS256-None] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[128-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[128-RS512-None] test/unit/auth/test_jwt_auth.py::test_authenticate_instance_sends_post_request_with_correct_params[128-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[16-RS256-None] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[16-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[16-RS512-None] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[16-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[32-RS256-None] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[32-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[32-RS512-None] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[32-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[128-RS256-None] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[128-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[128-RS512-None] test/unit/auth/test_jwt_auth.py::test_refresh_app_user_sends_post_request_with_correct_params[128-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[16-RS256-None] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[16-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[16-RS512-None] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[16-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[32-RS256-None] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[32-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[32-RS512-None] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[32-RS512-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[128-RS256-None] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[128-RS256-strong_password] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[128-RS512-None] test/unit/auth/test_jwt_auth.py::test_refresh_instance_sends_post_request_with_correct_params[128-RS512-strong_password]
HISTORY.rst boxsdk/auth/jwt_auth.py boxsdk/version.py
HISTORY.rst boxsdk/auth/jwt_auth.py boxsdk/version.py