The signature is ECDSA-SHA256-DER over the ASCII string
<usdid_uuid>.<timestamp>.<base64url(SPKI_P256_pubkey)> — i.e. the whole
three-part prefix before the final . — signed with the same EC P-256
private key the device used for IGUSDIDRegistrationMutation. Node
crypto.createVerify('SHA256').update(msg).verify({ key, dsaEncoding: 'der' }, sig)
confirms this on every sampled header (448 fresh/warm, 450 HAR).
Older builds embedded no public key: 429-class captures used the three-part
form <uuid>.<ts>.<sig> with the signature over <uuid>.<ts>. That is the
one-version archive form; 448+ adds the SPKI segment to the header and folds
it into the signed input.
The timestamp is always JWS.exp - 2 — i.e. iat + 3598 when the standard
3600s TTL is used. The header therefore expires ~2s before the registration
JWS.
Builds the
x-meta-usdidHTTP header value.Format observed on Instagram Android 448/450 (fresh Genymotion 448, warm AVD 448 and a 450 client HAR all agree):
The signature is ECDSA-SHA256-DER over the ASCII string
<usdid_uuid>.<timestamp>.<base64url(SPKI_P256_pubkey)>— i.e. the whole three-part prefix before the final.— signed with the same EC P-256 private key the device used forIGUSDIDRegistrationMutation. Nodecrypto.createVerify('SHA256').update(msg).verify({ key, dsaEncoding: 'der' }, sig)confirms this on every sampled header (448 fresh/warm, 450 HAR).Older builds embedded no public key: 429-class captures used the three-part form
<uuid>.<ts>.<sig>with the signature over<uuid>.<ts>. That is the one-version archive form; 448+ adds the SPKI segment to the header and folds it into the signed input.The
timestampis alwaysJWS.exp - 2— i.e.iat + 3598when the standard 3600s TTL is used. The header therefore expires ~2s before the registration JWS.