Skip to content

Instantly share code, notes, and snippets.

@sweis
Created May 12, 2023 17:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sweis/d2cb77ef6edb1d9f67fc79eb7500b010 to your computer and use it in GitHub Desktop.
Save sweis/d2cb77ef6edb1d9f67fc79eb7500b010 to your computer and use it in GitHub Desktop.
Decompiled snippet from ObtainConversationKey.invokeSuspend from Twitter 9.88 APK release -- Not original source
// The IV seems to be the ephemeral public key of the sender and is the header of the encrypted
// conversation key
byte[] ivMaybeEphemeralPublicKey = ArrayUtils.sliceCopy(0, encryptedConversationKey, 65);
int length = encryptedConversationKey.length - 65;
byte[] ciphertext = ArrayUtils.sliceCopy(65, encryptedConversationKey, length);
ECNamedCurveParameterSpec secp256r1Spec = SessionKeyEncrypter.secp256r1Spec();
ECPublicKeySpec spec =
new ECPublicKeySpec(secp256r1Spec.curve.decodePoint(ivMaybeEphemeralPublicKey), secp256r1Spec);
BCECPublicKey bCECPublicKey = new BCECPublicKey("ECDSA", spec, BouncyCastleProvider.CONFIGURATION);
PrivateKey privateKey = getDMKeys.PrivKey.privateKey;
byte[] sharedSecret = SessionKeyEncrypter.generateSecret(bCECPublicKey, privateKey);
byte[] decryptedBytes = SessionKeyEncrypter.deriveKeyAndEncrypt(Cipher.DECRYPT_MODE, sharedSecret, iv, ciphertext);
String decryptedConversationKey = new String(decryptedBytes, Charsets.utf8);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment