Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AES GCM decrypts only part #16

Open
fu-raz opened this issue Apr 5, 2024 · 1 comment
Open

AES GCM decrypts only part #16

fu-raz opened this issue Apr 5, 2024 · 1 comment

Comments

@fu-raz
Copy link

fu-raz commented Apr 5, 2024

I know you're probably not working on this anymore, but I'm hoping you'll at least see this message and might have an idea where I can look.

I'm trying to decrypt data using AES GCM. I can do this in node js perfectly fine and I've almost got it working in your library. I can authenticate the data and key using the AAD and tag, which works great. Then I can decrypt the payload, but it never decrypts the whole message, only a small part.

Full disclosure, I'm trying to decrypt the broadcast messages from Tuya devices, so I can (eventually) use them in an app called SignalRGB. I know how to do this in NodeJS, but their app only supports limited JS. So that's why I'm here. Your library is the only one so far that has been able to decrypt at least part of the data.

Here's a test script, assuming you import AES, MD5, GCM, Hex and Base64

const aad = Hex.parse('00000000000000000013000000f1');
const tag = Hex.parse('36521b69183234690ed71b27fea429b5');

const key = MD5.hash('yGAdlopoPVldABfn');
const payloadBase64 = 'gkfGIQ1HGkmfHBwFqN9mtmz0bWGMVIhllyfMdXM0GnnEu4FYtSeSVumBoNg6yQ0Zvy6vzZhrjpLheWVHwVrytFj1GXNqesVv2u0lyTuaaKtt41epfZbTJ53CUMCFiOyXBjJZlFzHDLVWdwNd6697JT5WVclT8LML7dQ1ZCRJ2RTRoccqa+qbXPtkuyknC6EqwfttCOlshpOB6eKNf0+mG8ZKPIAFIGKIorI/OZgsGy5o4sijBtbJzh9jGQQCp2hPwc57PXqmCnmzA7kvYJkt9XFW+DCS';
const payload = Base64.parse(payloadBase64);

const iv = Hex.parse('7dc8a528c958e1359c7b08ad');

var authtag = GCM.mac(AES, key, iv, aad, payload);

// Let's see if the data is correct
if (authtag.toString() !== tag.toString())
{
    console.log('Error authenticating data');
} else
{
    console.log('Key and data is valid');
    console.log(payload);
    console.log(payload.toString(Base64));

    let decrypted = AES.decrypt(payload.toString(Base64), key, {iv: iv, mode: GCM});
    console.log('Decrypted', decrypted);   
}

This is a 213 byte long encrypted json message. If I decrypt it in node js, it gives me exactly that. A 213 byte decrypted json message. When I use your library it gives me, in this case, 15 bytes of the decrypted json message. So it does decrypt correctly, it just stops randomly.

I have other examples where the library decrypts more, but never the full message. Do you have any clue where I should look?

Best regards,
Rick

@fu-raz
Copy link
Author

fu-raz commented Apr 5, 2024

From what I debugged so far is that it happens in the unpad function. In this example it calculates nPaddingBytes = 198, which it then strips from the WordArray, leaving only 15 bytes.

Removing the padding.unpad(finalProcessedBlocks); from BlockCipher.js worked, but I don't know if this now messes up other encryption modes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant