تقديم طلب من واجهة برمجة التطبيقات الكلاسيكية

إذا كنت تخطط فقط لإنشاء واجهة برمجة تطبيقات قياسية الطلبات، التي تناسب معظم من المطوّرين، يمكنك التخطّي إلىالتكامل البيانات. تصف هذه الصفحة صناعة طلبات البيانات من واجهة برمجة التطبيقات للحصول على بيانات السلامة، التي تتوافق مع نظام التشغيل Android 4.4 (واجهة برمجة التطبيقات المستوى 19) أو أعلى.

الاعتبارات

مقارنة الطلبات العادية والكلاسيكية

يمكنك إنشاء طلبات عادية أو طلبات كلاسيكية أو مزيج من الاثنين استنادًا إلى احتياجات أمان التطبيق ومكافحة إساءة الاستخدام. الطلبات العادية هي لجميع التطبيقات والألعاب ويمكن استخدامها للتحقق من أن أي حركة أو اتصال الخادم صادق، مع تفويض بعض الحماية ضد إعادة التشغيل إلى Google Play. يعد إنشاء الطلبات الكلاسيكية أكثر تكلفة فأنت مسئول عن تنفيذها بشكل صحيح للحماية من والتسلل وأنواع معينة من الهجمات. يجب تقليل عدد الطلبات الكلاسيكية كثيرًا من الطلبات العادية، على سبيل المثال، لمرة واحدة من حين لآخر للتحقق ما إذا كان الإجراء الذي يتخذ قيمة عالية أو حسّاسًا حقيقيًا

يوضح الجدول التالي الاختلافات الرئيسية بين نوعي الطلبات:

طلب البيانات من واجهة برمجة التطبيقات العادية طلب البيانات من واجهة برمجة التطبيقات الكلاسيكية
المتطلبات الأساسية
مطلوب إصدار حزمة تطوير البرامج (SDK) لنظام التشغيل Android بالحدّ الأدنى Android 5.0 (مستوى واجهة برمجة التطبيقات 21) أو إصدار أحدث الإصدار 4.4 من نظام التشغيل Android (المستوى 19 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث
متطلبات Google Play "متجر Google Play" وخدمات Google Play "متجر Google Play" وخدمات Google Play
تفاصيل عملية الدمج
يجب تحضير واجهة برمجة التطبيقات ✔️ (بضع ثوانٍ)
وقت الاستجابة المعتاد للطلبات بضع مئات من المللي ثانية بضع ثوانٍ
معدّل تكرار الطلب المحتمَل متكرر (فحص عند الطلب لأي إجراء أو طلب) غير متكرّر (عملية فحص لمرة واحدة للإجراءات ذات القيمة الأعلى أو الطلبات الأكثر حساسية)
عملية استبعاد للقناة لمهلة معيّنة تقل معظم عمليات الإحماء عن 10 ثوانٍ ولكنها تتضمن الاتصال بالخادم، لذلك يُنصح بتحديد مهلة طويلة (على سبيل المثال، دقيقة واحدة). يتم تقديم طلبات الحصول على بيان السلامة من جهة العميل تكون معظم الطلبات أقل من 10 ثوانٍ ولكنها تتضمّن اتصالًا بالخادم، لذا يُنصح باستخدام مهلة طويلة (دقيقة واحدة مثلاً).
الرمز المميّز لبيان السلامة
يحتوي على تفاصيل الجهاز والتطبيق والحساب ✔️ ✔️
التخزين المؤقت للرموز المميّزة خدمة تخزين مؤقت على الجهاز محمية من Google Play (يُفضَّل عدم النقر هنا.)
فك تشفير الرمز المميّز وإثبات ملكيته عبر خادم Google Play ✔️ ✔️
وقت الاستجابة المعتاد لطلبات فك التشفير من خادم إلى خادم 10 ثوانٍ من المللي ثانية مع مدى التوفّر إلى ثلاث تسعة 10 ثوانٍ من المللي ثانية مع مدى التوفّر إلى ثلاث تسعة
فك تشفير الرمز المميّز وإثبات ملكيته محليًا في بيئة خادم آمنة ✔️
فك تشفير الرمز المميّز والتحقّق من جهة العميل
حداثة بيان السلامة بعض عمليات التخزين المؤقت والتحديث التلقائي في Google Play تتم إعادة احتساب جميع البيانات عند كل طلب.
الحدود
الطلبات لكل تطبيق في اليوم 10000 بشكل تلقائي (يمكن طلب زيادة) 10000 بشكل تلقائي (يمكن طلب زيادة)
الطلبات لكل نسخة تطبيق في الدقيقة عمليات الإحماء: 5 في الدقيقة
رموز التكامل المميّزة: ما من حد أقصى علني*
الرموز المميّزة للتحقق من سلامة التطبيق: 5 في الدقيقة
الحماية
الحد من التلاعب والهجمات المماثلة استخدام الحقل requestHash استخدام الحقل nonce مع ربط المحتوى استنادًا إلى بيانات الطلب
الحد من عمليات إعادة التشغيل والهجمات المماثلة إجراءات التخفيف التلقائية من خلال Google Play استخدام الحقل nonce مع منطق جهة الخادم

* جميع الطلبات، بما فيها تلك التي لم تُفرض عليها قيود علنية، تخضع لحدود دفاعية غير علنية عند استخدام القيم العالية.

تقديم طلبات كلاسيكية نادرًا

يستهلك إنشاء رمز مميَّز للسلامة الوقت والبيانات والبطارية، ويتضمّن كل تطبيق الحدّ الأقصى لعدد الطلبات الكلاسيكية التي يمكنه إرسالها في اليوم. لذلك يجب عليك إجراء الطلبات الكلاسيكية فقط للتحقق من أعلى قيمة أو الإجراءات الأكثر حساسية صادقة عندما تريد ضمانًا إضافيًا لطلب عادي. إِنْتَ عدم إنشاء طلبات كلاسيكية لإجراءات عالية التكرار أو منخفضة القيمة. الإجراءات غير المستحسنة إجراء طلبات كلاسيكية في كل مرة ينتقل فيها التطبيق إلى المقدمة أو كل بضعة دقائق في الخلفية وتجنُّب الاتصال من عدد كبير من الأجهزة في في نفس الوقت. قد يتم تقييد التطبيقات التي تُجري عددًا كبيرًا جدًا من الطلبات الكلاسيكية إلى وحماية المستخدمين من عمليات التنفيذ غير الصحيحة.

تجنُّب بيانات التخزين المؤقت

يؤدي التخزين المؤقت للقرار إلى زيادة خطر الهجمات، مثل استخراج البيانات وإعادة تشغيلها حيث يُعاد استخدام بيان جيد من بيئة غير موثوق بها. إذا كنت التفكير في تقديم طلب كلاسيكي ثم تخزينه مؤقتًا لاستخدامه في وقت لاحق، ننصح باستخدامه بدلاً من ذلك لتنفيذ طلب عادي عند الطلب. الطلبات العادية بعض التخزين المؤقت على الجهاز، إلا أنّ Google Play يستخدم حماية إضافية والتقنيات اللازمة للتخفيف من خطر هجمات إعادة التشغيل والاستخراج.

استخدام حقل nonce لحماية الطلبات الكلاسيكية

توفّر واجهة برمجة التطبيقات Play Integrity API حقلاً يُسمى nonce، ويمكن استخدامه توفير حماية أكبر لتطبيقك من هجمات معيّنة، مثل إعادة التشغيل والتلاعب الهجمات. تعرض واجهة برمجة التطبيقات Play Integrity API القيمة التي حدّدتها في هذا الحقل، داخل استجابة السلامة الموقعة. اتبع بعناية الإرشادات حول كيفية إنشاء غير المرغوب فيها لحماية تطبيقك من الهجمات.

إعادة محاولة الطلبات الكلاسيكية باستخدام خوارزمية الرقود الأسي الثنائي

الظروف البيئية، مثل اتصال الإنترنت غير المستقر أو تحميل زائد على الجهاز، قد يؤدي إلى تعذُّر إجراء عمليات التحقّق من سلامة الجهاز. وهذا يمكن أن يؤدي إلى عدم إنشاء تصنيفات لجهاز موثوق به من ناحية أخرى إلى للتخفيف من هذه السيناريوهات، وتضمين خيار إعادة المحاولة مع التراجع الأسي.

نظرة عامة

مخطّط بياني للتسلسل يوضّح التصميم العالي المستوى لميزة Play Integrity
واجهة برمجة التطبيقات

عندما ينفِّذ المستخدم إجراءً عالي القيمة في تطبيقك تريد حمايته من خلال إجراء عملية التحقّق من السلامة، أكمِل الخطوات التالية:

  1. تنشئ الواجهة الخلفية من جهة الخادم لتطبيقك قيمة فريدة وترسلها إلى منطق العميل. وتشير الخطوات المتبقية إلى هذا المنطق باسم "التطبيق".
  2. ينشئ تطبيقك nonce من القيمة الفريدة ومحتوى السمة إجراء عالي القيمة. وتطلب بعد ذلك واجهة برمجة التطبيقات Play Integrity API، ما يؤدي إلى تمرير بيانات nonce
  3. يتلقّى تطبيقك بيانًا موقَّعًا ومشفّرًا من فريق Play Integrity. واجهة برمجة التطبيقات.
  4. يمرّر تطبيقك بيان التوقيع والمشفَّر إلى خلفية تطبيقك.
  5. وتُرسِل الخلفية في تطبيقك القرار إلى خادم Google Play. فريق يفك خادم Play تشفير البيانات ويتحقق منها، ويعرض النتائج إلى للواجهة الخلفية للتطبيق.
  6. تحدِّد خلفية تطبيقك كيفية المتابعة استنادًا إلى الإشارات الواردة في حمولة البيانات الخاصة بالرمز المميز.
  7. ترسل خلفية تطبيقك نتائج القرار إلى تطبيقك.

إنشاء رقم Nonce

عند حماية إجراء في تطبيقك باستخدام واجهة برمجة التطبيقات Play Integrity API، يمكنك: الاستفادة من الحقل nonce للتخفيف من أنواع معينة من الهجمات، مثل هجمات التلاعب بلعبة الوسيط (PITM) وهجمات إعادة التشغيل. Play تعرض واجهة برمجة التطبيقات Integrity API القيمة التي حدّدتها في هذا الحقل داخل استجابة السلامة.

يجب أن تكون القيمة التي تم ضبطها في الحقل nonce بالتنسيق الصحيح:

  • String
  • عدم أمان عنوان URL
  • تم ترميزه كـ Base64 وغير قابل للالتفاف
  • 16 حرفًا كحدّ أدنى
  • 500 حرف كحدّ أقصى

في ما يلي بعض الطرق الشائعة لاستخدام الحقل nonce في Play Integrity API. للحصول على أعلى مستوى من الحماية من nonce، يمكنك دمج: الطرق أدناه.

تضمين تجزئة طلب للحماية من التلاعب

يمكنك استخدام المَعلمة nonce في طلب بيانات من واجهة برمجة التطبيقات الكلاسيكية بالطريقة نفسها المستخدَمة في معلَمة requestHash في طلب بيانات عادي من واجهة برمجة التطبيقات لحماية محتوى طلب ضد التلاعب.

عند طلب بيان سلامة:

  1. احتساب ملخص لجميع معلَمات الطلب المهمة (مثل SHA256 لعنصر ثابت) طلب التسلسل) من إجراء المستخدم أو طلب الخادم الذي يحدث.
  2. استخدِم setNonce لضبط الحقل nonce على قيمة الملخّص الذي تم حسابه.

عند تلقّي بيان سلامة:

  1. فك ترميز الرمز المميز للأمان والتحقق منه، واحصل على الملخص من الحقل "nonce".
  2. احتساب ملخص للطلب بالطريقة نفسها المستخدَمة في التطبيق (على سبيل المثال، SHA256 لتسلسل طلب ثابت).
  3. مقارنة الملخّصات من جهة التطبيق ومن جهة الخادم إذا لم يتطابقا، فسيتم أن يكون الطلب غير موثوق به.

تضمين قيم فريدة للحماية من هجمات إعادة التشغيل

لمنع المستخدمين الضارين من إعادة استخدام الردود السابقة من واجهة برمجة التطبيقات Play Integrity API، يمكنك استخدام الحقل nonce لتحديد كل منها بشكل فريد .

عند طلب بيان سلامة:

  1. الحصول على قيمة فريدة عامة بطريقة لا يمكن للمستخدمين الضارين توقّعها فعلى سبيل المثال، يمكن إنشاء رقم عشوائي آمن بطريقة مشفرة على جانب الخادم قيمة أو معرفًا موجودًا مسبقًا مثل جلسة أو معرِّف معاملة. يتمثل الخيار الأبسط والأقل أمانًا في إنشاء قائمة عشوائية الرقم على الجهاز. نوصي بإنشاء قيم يبلغ حجمها 128 بت أو أكبر.
  2. يمكنك طلب setNonce() لضبط الحقل nonce على القيمة الفريدة من الخطوة 1.

عند تلقّي بيان سلامة:

  1. فك ترميز الرمز المميز للسلامة والتحقق منه، والحصول على القيمة الفريدة من الحقل "nonce".
  2. إذا تم إنشاء القيمة من الخطوة 1 على الخادم، تأكَّد من أنّ التي تم الحصول عليها كانت إحدى القيم التي تم إنشاؤها، وأنه يتم للمرة الأولى (يجب أن يحتفظ خادمك بسجل ملفات الإنترنت التي تم إنشاؤها، القيم لمدة مناسبة). في حال استخدام القيمة الفريدة المستلمة من قبل أو لا يظهر في السجلّ، يجب رفض الطلب
  3. وبخلاف ذلك، إذا تم إنشاء القيمة الفريدة على الجهاز، تأكَّد من هذه القيمة هي المستلَمة للمرة الأولى (يحتاج الخادم إلى الاحتفاظ سجل القيم التي تمت رؤيتها بالفعل لمدة مناسبة). إذا تم استلام سبق أن تم استخدام قيمة فريدة، يُرجى رفض الطلب.

الجمع بين وسائل الحماية ضد هجمات التلاعب وإعادة التشغيل (يُنصَح به)

من الممكن استخدام الحقل nonce للحماية من التلاعب بالتطبيقات هجوم إعادة تشغيل الهجوم في الوقت نفسه. ولإجراء ذلك، عليك إنشاء القيمة الفريدة مثل الموضحة أعلاه، وتضمينها كجزء من طلبك. ثم احسب لطلب التجزئة، مع الحرص على تضمين القيمة الفريدة كجزء من التجزئة. إنّ عملية التنفيذ التي تجمع بين النهجين على النحو التالي:

عند طلب بيان سلامة:

  1. يبدأ المستخدم الإجراء ذي القيمة العالية.
  2. الحصول على قيمة فريدة لهذا الإجراء كما هو موضّح في تضمين فريد القيم للحماية من هجمات إعادة التشغيل.
  3. يمكنك إعداد الرسالة التي تريد حمايتها. تضمين القيمة الفريدة من الخطوة 2 في الرسالة.
  4. يحتسب تطبيقك ملخصًا للرسالة التي يريد حمايتها، وذلك لأنّ الموضحة في تضمين تجزئة طلب للحماية من التلاعب. نظرًا لأن الرسالة تحتوي على القيمة الفريدة فإن القيمة الفريدة هي جزء من التجزئة.
  5. استخدِم setNonce() لضبط الحقل nonce على الملخّص المحتسَب من الخطوة السابقة.

عند تلقّي بيان سلامة:

  1. الحصول على القيمة الفريدة من الطلب
  2. فك ترميز الرمز المميز للأمان والتحقق منه، واحصل على الملخص من الحقل "nonce".
  3. كما هو موضَّح في مقالة تضمين تجزئة طلب للحماية من التلاعب وإعادة حساب الملخص على الخادم، والتحقق من تطابقه الملخص الذي تم الحصول عليه من رمز السلامة.
  4. كما هو موضح في تضمين قيم فريدة للحماية من إعادة التشغيل الهجمات، في التحقق من صلاحية القيمة الفريدة.

يوضح الرسم التخطيطي للتسلسل التالي هذه الخطوات باستخدام علامة nonce:

مخطط تسلسلي يوضّح كيفية الحماية من التلاعب وإعادة التشغيل
هجمات

طلب بيان سلامة

بعد إنشاء nonce، يمكنك طلب بيان سلامة من Google. اللعب. للقيام بذلك، أكمل الخطوات التالية:

  1. أنشئ IntegrityManager، كما هو موضّح في الأمثلة التالية.
  2. إنشاء IntegrityTokenRequest، وتوفير nonce من خلال setNonce() في أداة الإنشاء المرتبطة. تطبيقات تم توزيعها حصريًا خارج Google Play وحِزم تطوير البرامج (SDK) أيضًا إلى تحديد خدمات Google Cloud رقم المشروع من خلال طريقة setCloudProjectNumber(). التطبيقات على Google ترتبط منصة Play بمشروع على السحابة الإلكترونية في Play Console ولا تحتاج إلى يمكنك ضبط رقم المشروع على السحابة الإلكترونية في الطلب.
  3. يمكنك استخدام المدير للاتصال بـ requestIntegrityToken()، وتوفير IntegrityTokenRequest

Kotlin

// Receive the nonce from the secure server.
val nonce: String = ...

// Create an instance of a manager.
val integrityManager =
    IntegrityManagerFactory.create(applicationContext)

// Request the integrity token by providing a nonce.
val integrityTokenResponse: Task<IntegrityTokenResponse> =
    integrityManager.requestIntegrityToken(
        IntegrityTokenRequest.builder()
             .setNonce(nonce)
             .build())

Java

import com.google.android.gms.tasks.Task; ...

// Receive the nonce from the secure server.
String nonce = ...

// Create an instance of a manager.
IntegrityManager integrityManager =
    IntegrityManagerFactory.create(getApplicationContext());

// Request the integrity token by providing a nonce.
Task<IntegrityTokenResponse> integrityTokenResponse =
    integrityManager
        .requestIntegrityToken(
            IntegrityTokenRequest.builder().setNonce(nonce).build());

الانسجام

IEnumerator RequestIntegrityTokenCoroutine() {
    // Receive the nonce from the secure server.
    var nonce = ...

    // Create an instance of a manager.
    var integrityManager = new IntegrityManager();

    // Request the integrity token by providing a nonce.
    var tokenRequest = new IntegrityTokenRequest(nonce);
    var requestIntegrityTokenOperation =
        integrityManager.RequestIntegrityToken(tokenRequest);

    // Wait for PlayAsyncOperation to complete.
    yield return requestIntegrityTokenOperation;

    // Check the resulting error code.
    if (requestIntegrityTokenOperation.Error != IntegrityErrorCode.NoError)
    {
        AppendStatusLog("IntegrityAsyncOperation failed with error: " +
                requestIntegrityTokenOperation.Error);
        yield break;
    }

    // Get the response.
    var tokenResponse = requestIntegrityTokenOperation.GetResult();
}

مدمجة مع المحتوى

/// Create an IntegrityTokenRequest opaque object.
const char* nonce = RequestNonceFromServer();
IntegrityTokenRequest* request;
IntegrityTokenRequest_create(&request);
IntegrityTokenRequest_setNonce(request, nonce);

/// Prepare an IntegrityTokenResponse opaque type pointer and call
/// IntegerityManager_requestIntegrityToken().
IntegrityTokenResponse* response;
IntegrityErrorCode error_code =
        IntegrityManager_requestIntegrityToken(request, &response);

/// ...
/// Proceed to polling iff error_code == INTEGRITY_NO_ERROR
if (error_code != INTEGRITY_NO_ERROR)
{
    /// Remember to call the *_destroy() functions.
    return;
}
/// ...
/// Use polling to wait for the async operation to complete.
/// Note, the polling shouldn't block the thread where the IntegrityManager
/// is running.

IntegrityResponseStatus response_status;

/// Check for error codes.
IntegrityErrorCode error_code =
        IntegrityTokenResponse_getStatus(response, &response_status);
if (error_code == INTEGRITY_NO_ERROR
    && response_status == INTEGRITY_RESPONSE_COMPLETED)
{
    const char* integrity_token = IntegrityTokenResponse_getToken(response);
    SendTokenToServer(integrity_token);
}
/// ...
/// Remember to free up resources.
IntegrityTokenRequest_destroy(request);
IntegrityTokenResponse_destroy(response);
IntegrityManager_destroy();

فك تشفير بيان السلامة والتحقّق منه

عندما تطلب بيان سلامة، توفّر واجهة برمجة التطبيقات Play Integrity API رمز الاستجابة السريعة. تصبح السمة nonce التي تُدرجها في طلبك جزءًا من رمز الاستجابة السريعة.

تنسيق الرمز المميّز

ويكون الرمز المميّز عبارة عن رمز JSON المميّز للويب (JWT) مدمج، هو JSON Web Encryption (JWE). توقيع الويب JSON (JWS) يتم تمثيل مكونات JWE وJWS باستخدام علامة التقسيم .

يتم دعم خوارزميات التشفير / التوقيع بشكل جيد عبر العديد من JWT عمليات التنفيذ:

  • يستخدم JWE A256KW alg A256GCM for enc

  • تستخدم شركة JWS ES256.

فك التشفير وإثبات الملكية على خوادم Google (خيار يُنصَح به)

تتيح لك واجهة برمجة التطبيقات Play Integrity API فك تشفير بيان السلامة والتحقّق من صحته في خوادم Google التي تعزز أمان تطبيقك. للقيام بذلك، أكمل هذه الخطوات:

  1. إنشاء حساب خدمة ضمن مشروع Google Cloud المرتبط بتطبيقك
  2. على خادم تطبيقك، عليك جلب رمز الدخول من حساب الخدمة. بيانات الاعتماد باستخدام نطاق playintegrity، وتقديم الطلب التالي:

    playintegrity.googleapis.com/v1/PACKAGE_NAME:decodeIntegrityToken -d \
    '{ "integrity_token": "INTEGRITY_TOKEN" }'
  3. اقرأ استجابة JSON.

فك التشفير وإثبات الملكية على الجهاز

إذا اخترت إدارة وتنزيل مفاتيحك الخاصة بتشفير الردود، يمكنك تنفيذ ما يلي: فك تشفير الرمز المميز الذي تم إرجاعه والتحقق منه في بيئة الخادم الآمنة الخاصة بك. يمكنك الحصول على الرمز المميّز الذي تم عرضه باستخدام IntegrityTokenResponse#token(). .

يوضح المثال التالي كيفية فك ترميز مفتاح AES والمفتاح العام بترميز DER. مفتاح EC لإثبات صحة التوقيع من Play Console إلى لغات معيّنة (لغة برمجة Java، في حالتنا) في خلفية التطبيق. ملاحظة أن المفاتيح مشفّرة بترميز base64.

Kotlin

// base64OfEncodedDecryptionKey is provided through Play Console.
var decryptionKeyBytes: ByteArray =
    Base64.decode(base64OfEncodedDecryptionKey, Base64.DEFAULT)

// Deserialized encryption (symmetric) key.
var decryptionKey: SecretKey = SecretKeySpec(
    decryptionKeyBytes,
    /* offset= */ 0,
    AES_KEY_SIZE_BYTES,
    AES_KEY_TYPE
)

// base64OfEncodedVerificationKey is provided through Play Console.
var encodedVerificationKey: ByteArray =
    Base64.decode(base64OfEncodedVerificationKey, Base64.DEFAULT)

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

Java

// base64OfEncodedDecryptionKey is provided through Play Console.
byte[] decryptionKeyBytes =
    Base64.decode(base64OfEncodedDecryptionKey, Base64.DEFAULT);

// Deserialized encryption (symmetric) key.
SecretKey decryptionKey =
    new SecretKeySpec(
        decryptionKeyBytes,
        /* offset= */ 0,
        AES_KEY_SIZE_BYTES,
        AES_KEY_TYPE);

// base64OfEncodedVerificationKey is provided through Play Console.
byte[] encodedVerificationKey =
    Base64.decode(base64OfEncodedVerificationKey, Base64.DEFAULT);
// Deserialized verification (public) key.
PublicKey verificationKey =
    KeyFactory.getInstance(EC_KEY_TYPE)
        .generatePublic(new X509EncodedKeySpec(encodedVerificationKey));

بعد ذلك، استخدِم هذه المفاتيح لفك تشفير رمز السلامة (جزء JWE) أولاً، ثم التحقق من جزء JWS المتداخل واستخراجه.

Kotlin

val jwe: JsonWebEncryption =
    JsonWebStructure.fromCompactSerialization(integrityToken) as JsonWebEncryption
jwe.setKey(decryptionKey)

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

val jws: JsonWebSignature =
    JsonWebStructure.fromCompactSerialization(compactJws) as JsonWebSignature
jws.setKey(verificationKey)

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

Java

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();

الحمولة الناتجة هي رمز مميّز بنص عادي يحتوي على التكامل البيانات.