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

AesKeyWrap integrity check failed for A256KW for alg #202

Open
cupatil opened this issue Nov 7, 2022 · 16 comments
Open

AesKeyWrap integrity check failed for A256KW for alg #202

cupatil opened this issue Nov 7, 2022 · 16 comments

Comments

@cupatil
Copy link

cupatil commented Nov 7, 2022

Hi @dvsekhvalnov,

I am trying to decrypt the play integrity token using this lib. The JWE uses A256KW for [alg] and A256GCM for [enc]

below are the code I am trying to execute and it throws the AesKeyWrap integrity check failed error

 var publicKey = new Jose.Jwk();
 
 publicKey.Kty = "oct";
 publicKey.K = DECRYPTION_KEY;
 
 var jweToken=Jose.JWE.Decrypt(tokenString, publicKey);
 log.LogInformation(jweToken.Plaintext);

Please let me know if I am doing something wrong here.

@dvsekhvalnov
Copy link
Owner

dvsekhvalnov commented Nov 7, 2022

Hi @cupatil

are you facing any error? :) Nothing mentioned in a ticket.

And typically you want Jose.JWT.Decode(), not Jose.JWE.Decrypt(), unless you truly working with RFC 7516 (Json serialization).

@cupatil
Copy link
Author

cupatil commented Nov 7, 2022

Hi @dvsekhvalnov ,

In both ways I am getting AesKeyWrap integrity check failed error.

I am trying to write equivalent code in c# using this lib. Below are the java code

JsonWebEncryption jwe =
    (JsonWebEncryption)JsonWebStructure
        .fromCompactSerialization(integrityToken);
jwe.setKey(decryptionKey);

// This also decrypts the JWE token.
String compactJws = jwe.getPayload();

JsonWebSignature jws =
    (JsonWebSignature) JsonWebStructure.fromCompactSerialization(compactJws);
jws.setKey(verificationKey);

// This also verifies the signature.
String payload = jws.getPayload();

Can you please suggest? Above code was written with Jose4J.

@dvsekhvalnov
Copy link
Owner

Looks like you only need compact serialization, not json, so this should make it:

var decrypted = Jose.JWT.Decode(integrityToken, decryptionKey)
var payload = Jose.JWT.Decode(decrypted, verificationKey)

AesKeyWrap integrity check failed - usually means you messed up keys. If you have example token and key, feel free to share, i can try to run myself. (Please don't share real keys).

@cupatil
Copy link
Author

cupatil commented Nov 8, 2022

Hi @dvsekhvalnov,
Thanks for the quick help, 1 line of code works for me. and In second decrypted text (JWS uses ES256.) It gives me error "EcdsaUsingSha algorithm expects key to be of CngKey, ECDsa or Jwk types with kty='EC'."

Now I am trying to convert base64 encoded verification key to EC (ES256) public key using JWK can you please suggest how this is possible through this lib. Please suggest.

In java below code works to generate the key:

var encodedVerificationKey: ByteArray =
    Base64.decode(base64OfEncodedVerificationKey, Base64.DEFAULT)

// Deserialized verification (public) key.
var verificationKey: PublicKey = KeyFactory.getInstance(EC_KEY_TYPE)
    .generatePublic(X509EncodedKeySpec(encodedVerificationKey))

Thanks in advance.

@dvsekhvalnov
Copy link
Owner

dvsekhvalnov commented Nov 8, 2022

@cupatil, what's inside your base64 encoded key? Is it just PEM key? or JWK?

If you can post base64 url string - will help greatly to understand issue :)

@cupatil
Copy link
Author

cupatil commented Nov 8, 2022

@dvsekhvalnov The key is provided from the play console Its base64OfEncodedVerificationKey

Here is the sample key:
MFkwEwYHKoZIzj0CAQYIKo..........................................................................................uwsnZtn8ow==

I need to generate ECC key from this. I have tried some manual approach mentioned below.

  var verifyKey = Convert.FromBase64String(verificationKey); 
  var pubKeyX = verifyKey.Skip(27).Take(32).ToArray();
  var pubKeyY = verifyKey.Skip(59).Take(32).ToArray();
  var eccKey= EccKey.New(pubKeyX, pubKeyY);
  var payload = Jose.JWT.Decode(jweToken, eccKey);

It works for me. Can you please suggest is it the write way to do?

@dvsekhvalnov
Copy link
Owner

Can you post full base64 string? can't decode and check what's inside.

EccKey.New(pubKeyX, pubKeyY) - you can use it to construct Elliptic CngKey if you are sure pubX and pubY are correct key material.

@dvsekhvalnov
Copy link
Owner

dvsekhvalnov commented Nov 8, 2022

Is your verification key string after Base64 decode starts with -----BEGIN EC PRIVATE KEY----- ?

@Jitendran
Copy link

Hi @dvsekhvalnov , I am facing same type of issue when I implement Play Integrity in my Android app.
I am facing "org.jose4j.lang.IntegrityException: A256KW key unwrap/decrypt failed." exception
In try catch block that exception get.
var jwe = JsonWebStructure.fromCompactSerialization(integrityToken) as JsonWebEncryption
jwe.key = decryptionKey
var compactJws: String? = null
try {
compactJws = jwe.payload
} catch (e: JoseException) {
Log.d(TAG, e.message!!)
}
Please help me....

@dvsekhvalnov
Copy link
Owner

Hey @Jitendran ,
i need some details to help with those kind of issues: your code that producing or verifying tokens with jose-jwt library and ideally keys if not secret.

Would suggest to open separate issue and add details.

@Jitendran
Copy link

Jitendran commented Apr 24, 2023

Hi @dvsekhvalnov Thanks for your reply ...
As you suggested I have created 1 new separate issue , please open this below link

#226

@Jitendran
Copy link

Jitendran commented Apr 24, 2023

Hi @cupatil , Can you help me on this issue ?
#226

I think you are also tried Play-Integrity in Android Kotlin.

Please help me on this, because I am stuck and not getting any solution from any where.

@dishanphilips
Copy link

Hi :)

You can decode the Google Attestation Statement in the following way in C#

var decryptionKey = Convert.FromBase64String("<DECRYPTION KEY>");
var verificationKey = Convert.FromBase64String("<VERIFICATION KEY>");
var signedAttestationStatement = "<ATTESTATION STATEMENT>";

var ecDsa = ECDsa.Create();
ecDsa.ImportSubjectPublicKeyInfo(new ReadOnlySpan<byte>(verificationKey), out _);

var decrypted = Jose.JWT.Decode(signedAttestationStatement, decryptionKey);
var payload = Jose.JWT.Decode(decrypted, ecDsa);

@Jitendran
Copy link

Jitendran commented Apr 27, 2023

Hi @dishanphilips Thanks for your reply, we are testing the on the app which was not live in PlayStore, but we upload the app on PlayStore after that we are not facing this issue now.
Thanks to @cupatil as well he help us via phone communication.

@Jitendran
Copy link

Jitendran commented Apr 27, 2023

Hi :)

You can decode the Google Attestation Statement in the following way in C#

var decryptionKey = Convert.FromBase64String("<DECRYPTION KEY>");
var verificationKey = Convert.FromBase64String("<VERIFICATION KEY>");
var signedAttestationStatement = "<ATTESTATION STATEMENT>";

var ecDsa = ECDsa.Create();
ecDsa.ImportSubjectPublicKeyInfo(new ReadOnlySpan<byte>(verificationKey), out _);

var decrypted = Jose.JWT.Decode(signedAttestationStatement, decryptionKey);
var payload = Jose.JWT.Decode(decrypted, ecDsa);

What will be used in place of ATTESTATION STATEMENT ?

@dishanphilips
Copy link

The attestation statement that you received from the google play integrity api. Looking at you code above that would be : integrityToken

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

4 participants