How is there a negative salt or verified generated here while confirming a device for AWS Cognito?

199 views Asked by At

I am trying to confirm a device for AWS Cognito userpool. Following this.

I have to generate salt and password verifier as shown above. I.e
AWS Instructions
N and g are constants which are working properly.

But I'm having issues generating salt and password_verifier.
My current code sometimes works and sometimes doesn't.

def confirm_device(self, access_token, device_key, device_group_key, device_name=None, device_secret_verifier_config=None, client=None):
        boto_client = self.client or client
        if device_secret_verifier_config is None:
            salt = base64.b64encode(os.urandom(16)).decode('utf-8')
            random_password = base64.b64encode(os.urandom(40)).decode('utf-8')
            fullPassword = hash_sha256((device_group_key + self.username + ":" + random_password).encode('utf-8'))
            print("salt:", salt)
            print("device_group_key:", device_group_key)
            print("self.username:", self.username)
            print("random_password:", random_password)
            print("fullPassword:", fullPassword)

            passwordVerifier = pow(self.g, int(hash_sha256(
                (salt+fullPassword).encode('utf-8')), 16), self.big_n)
            print("passwordVerifier(long):", passwordVerifier)
            print("passwordVerifier(hex):", long_to_hex(passwordVerifier))
            device_secret_verifier_config = {
                "Salt": salt,
                "PasswordVerifier": long_to_hex(passwordVerifier)
            }

        response = boto_client.confirm_device(
            AccessToken=access_token,
            DeviceKey=device_key,
            DeviceSecretVerifierConfig=device_secret_verifier_config,
            DeviceName=device_name
        )
        return response

But sometimes the error I get is:

salt: yWCYwovPHPdYDPHhFrzKyg==
device_group_key: -0XBvPE09
self.username: [email protected]
random_password: pMR5cfS6FQnlAPm29LUDsErCc4aHCWMeqdGd2bcLZE3B0JG+RdOIyQ==
fullPassword: 1c29cfd97eb625829c6e8be3f9e823aa6b31b67ab39fe740e2ca6c654a9fb2a4
passwordVerifier(long): 636457470178471904602170294676132479527541618816078159926177246616820897931582354291256594700415979158362904848368215242517842246766722898352095950523415359512357135197644075156606305662197061622728011105893182896162600753980094747735968814947101806903320728940805295632888008937316996027809342812704675418816249058865169271618040775863712076049170826330252269036286588635452953613476526645046214559389852654846575848033111552003464182862296017216580460285015596444875087851514771404704977469707008223759561136986946262710161898233816711133328591069449690694615702797407859336821889381491140916683745161809644520490696169384473969975145822796719767469913712153649791894201733271080629680267104204269975456911759375158192425262696128327617882909774776615228610638458004118564487756755986578770741373069124440583371593426000651529979502212353120495649418999831541483473307834802627811270678065961013328057290361895641632584650
passwordVerifier(hex): 1c0ba3b731eb47c4f6abc4f6a3e5a690a6d4b12727eac92469174cea46fc39b7f0566324032ccaf8c84851077ecd139b2b4044e98935e05d06c2aac5863b43ee6e96959f8d4c6beacae44f0100949e6994610abe350ad54821e7292ba809195a2086ce89c5f99bd188233484b376e82e535c4b1c9b2e5d0d2bcdfdaea4d9f071d8feac483471b1f29870bb6f116577ccede75a6a12a9f55ddec8b3ba90124f5af0d0833f728b1572c28f4524db6373f01379cbc9712f7a435aac17f65a6927b16a05941a1ee46a9186933090ab83c0d02b6834b765c3fdc07f7b0126b5e410905ec82c7331faeed5b7aa8dd4ab39c8d32c4cb79291ffcb7ad58677473d22761d48957b1929252eee3a1d9c976e1f890e706311015b3c5deacb7888bb14a3bf4331f5d05c21b72dd40f5d24c8e188c7c83e3524f63a9e7ed65abff5bb56d0a7c95c546edeba82588ab1f7560803a778b6774eca45af032c280b409bc89601cf0ade994d320c37574b98a1a7aa87faf68ec6a2447589240c810080578fae2db3ca
Traceback (most recent call last):
  File "/Users/varungawande/Desktop/test/./srp_flow.py", line 63, in <module>
    srp_test(username=username, password=password, pool_id=userpoolId, client_id=clientID, region=region)
  File "/Users/varungawande/Desktop/test/./srp_flow.py", line 58, in srp_test
    confirmResp = awssrp.confirm_device(accessToken, deviceKey, deviceGroupKey, deviceName)
  File "/Users/varungawande/Desktop/test/aws_srp.py", line 293, in confirm_device
    response = boto_client.confirm_device(
  File "/Users/varungawande/miniconda3/lib/python3.9/site-packages/botocore/client.py", line 530, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/Users/varungawande/miniconda3/lib/python3.9/site-packages/botocore/client.py", line 960, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.errorfactory.InvalidParameterException: An error occurred (InvalidParameterException) when calling the ConfirmDevice operation: Found negative value for salt or password verifier.

I don't see how the salt or password can be negative.
I wonder if it's due to the padding in hash_sha256()

def hash_sha256(buf):
    """AuthenticationHelper.hash"""
    a = hashlib.sha256(buf).hexdigest()
    return (64 - len(a)) * '0' + a

The issue is that sometimes the randomly generated salts and verifiers work, but often they don't.
Once it generated:

salt = "LcpjRzthZ+lSQ6rfQWxlTA=="
random_password = "Xx5OmQ84mU+RLRfAhWAfVr9cn/K75sGZIe7SY2noWnEv6ojW0rkmXw=="

Then the ConfirmDevice call would work. I'm not understanding why some values work and some don't.

0

There are 0 answers