diff --git a/CHANGELOG.md b/CHANGELOG.md
index edb66fd..2e263cb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,9 @@
 
 ## 5.1.0 (under development)
 
+* Ignored HMAC character capitalization
+  ([#93](https://github.com/laterpay/laterpay-client-python/issues/93))
+
 ## 5.0.0
 
 * Removed the following long deprecated methods from the
diff --git a/laterpay/signing.py b/laterpay/signing.py
index 863fa05..164cba9 100644
--- a/laterpay/signing.py
+++ b/laterpay/signing.py
@@ -27,6 +27,7 @@ def time_independent_HMAC_compare(a, b):
     if len(a) != len(b):
         return False
     result = 0
+    a, b = a.lower(), b.lower()
     for x, y in zip(a, b):
         result |= ord(x) ^ ord(y)
     return result == 0

Ignore capitalization when checking HMACs
`laterpay.signing.time_independent_HMAC_compare()` treats hashes `12ab3` and `12AB3` as different. Let's not do that.
diff --git a/tests/test_signing.py b/tests/test_signing.py
index ce4742d..7874b13 100644
--- a/tests/test_signing.py
+++ b/tests/test_signing.py
@@ -138,8 +138,9 @@ class TestSigningHelper(unittest.TestCase):
 
         secret = 'secret'
 
+        # Use some upper case characters to test for issue #93
         verified = signing.verify(
-            b'346f3d53ad762f3ed3fb7f2427dec2bbfaf0338bb7f91f0460aff15c',
+            b'346f3d53ad762f3ed3fb7f2427deC2BBFAF0338BB7F91F0460AFF15C',
             secret,
             params,
             url,
@@ -153,8 +154,9 @@ class TestSigningHelper(unittest.TestCase):
             'param2': ['value2', 'value3'],
         }
         url = u'https://endpoint.com/api'
+        # Use some upper case characters to test for issue #93
         verified = signing.verify(
-            u'346f3d53ad762f3ed3fb7f2427dec2bbfaf0338bb7f91f0460aff15c',
+            u'346F3D53AD762F3ED3FB7F2427DEc2bbfaf0338bb7f91f0460aff15c',
             u'secret',
             params,
             url,

pip install -e .
parse_log_pytest
pytest
pytest pytest-cov pytest-xdist pytest-mock pytest-asyncio flake8 coverage pydocstyle furl mock responses
3.5
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs @ file:///opt/conda/conda-bld/attrs_1642510447205/work
certifi==2021.5.30
charset-normalizer==2.0.12
coverage==6.2
execnet==1.9.0
flake8==5.0.4
furl==2.1.4
idna==3.10
importlib-metadata==4.2.0
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
-e git+https://github.com/laterpay/laterpay-client-python.git@efe5ec2ff1a6b4020ae081c7491c7f9eca22cc4e#egg=laterpay_client
mccabe==0.7.0
mock==5.2.0
more-itertools @ file:///tmp/build/80754af9/more-itertools_1637733554872/work
orderedmultidict==1.0.1
packaging @ file:///tmp/build/80754af9/packaging_1637314298585/work
pluggy @ file:///tmp/build/80754af9/pluggy_1615976315926/work
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pycodestyle==2.9.1
pydocstyle==6.3.0
pyflakes==2.5.0
pyparsing @ file:///tmp/build/80754af9/pyparsing_1635766073266/work
pytest==6.2.4
pytest-asyncio==0.16.0
pytest-cov==4.0.0
pytest-mock==3.6.1
pytest-xdist==3.0.2
requests==2.27.1
responses==0.17.0
six==1.17.0
snowballstemmer==2.2.0
toml @ file:///tmp/build/80754af9/toml_1616166611790/work
tomli==1.2.3
typing_extensions @ file:///opt/conda/conda-bld/typing_extensions_1647553014482/work
urllib3==1.26.20
zipp @ file:///tmp/build/80754af9/zipp_1633618647012/work

name: laterpay-client-python
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
  - attrs=21.4.0=pyhd3eb1b0_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - importlib_metadata=4.8.1=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_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
  - more-itertools=8.12.0=pyhd3eb1b0_0
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=21.3=pyhd3eb1b0_0
  - pip=21.2.2=py36h06a4308_0
  - pluggy=0.13.1=py36h06a4308_0
  - py=1.11.0=pyhd3eb1b0_0
  - pyparsing=3.0.4=pyhd3eb1b0_0
  - pytest=6.2.4=py36h06a4308_2
  - 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
  - toml=0.10.2=pyhd3eb1b0_0
  - typing_extensions=4.1.1=pyh06a4308_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.6.0=pyhd3eb1b0_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - charset-normalizer==2.0.12
      - coverage==6.2
      - execnet==1.9.0
      - flake8==5.0.4
      - furl==2.1.4
      - idna==3.10
      - importlib-metadata==4.2.0
      - mccabe==0.7.0
      - mock==5.2.0
      - orderedmultidict==1.0.1
      - pycodestyle==2.9.1
      - pydocstyle==6.3.0
      - pyflakes==2.5.0
      - pytest-asyncio==0.16.0
      - pytest-cov==4.0.0
      - pytest-mock==3.6.1
      - pytest-xdist==3.0.2
      - requests==2.27.1
      - responses==0.17.0
      - six==1.17.0
      - snowballstemmer==2.2.0
      - tomli==1.2.3
      - urllib3==1.26.20
prefix: /opt/conda/envs/laterpay-client-python

tests/test_signing.py::TestSigningHelper::test_verify_byte_signature tests/test_signing.py::TestSigningHelper::test_verify_unicode_signature
tests/test_signing.py::TestSigningHelper::test_create_message_bytestrings tests/test_signing.py::TestSigningHelper::test_create_message_sorting_and_combining_params tests/test_signing.py::TestSigningHelper::test_create_message_sorting_and_combining_params_omdict tests/test_signing.py::TestSigningHelper::test_create_message_unicode tests/test_signing.py::TestSigningHelper::test_create_message_wrong_method tests/test_signing.py::TestSigningHelper::test_normalise_param_structure tests/test_signing.py::TestSigningHelper::test_sign tests/test_signing.py::TestSigningHelper::test_sign_unicode_secret tests/test_signing.py::TestSigningHelper::test_sort_params tests/test_signing.py::TestSigningHelper::test_sort_params_public_deprecation tests/test_signing.py::TestSigningHelper::test_url_verification tests/test_signing.py::TestSigningHelper::test_verify_invalid_unicode_signature tests/test_signing.py::TestSigningHelper::test_verify_iterable_signature
CHANGELOG.md laterpay/signing.py
CHANGELOG.md laterpay/signing.py