تخطَّ إلى المحتوى
getnextpdf.com

Enterprise الإصدار

إخفاء المعلومات — مرجع متعمّق

يوثّق هذا المرجع المتعمّق قناة إخفاء المعلومات في ⁨NextPDF Enterprise⁩. تُخفي القناة حمولة مُشفّرة داخل تعديلات التقنين (kerning) الرقمية في مصفوفة إظهار النص ⁨TJ⁩. تملك أربعة رموز عامة: ⁨SteganographyEncoder⁩ و⁨SteganographyDecoder⁩ و⁨SteganographyConfig⁩ و⁨SteganographyCapacity⁩. يشتقّ المُرمِّز مفتاحًا باستخدام ⁨HKDF-SHA-256⁩، ويُشفّر الحمولة بخوارزمية ⁨AEAD⁩، ويُعيد إزاحات تقنين لكل موضع. يعكس المُفكِّك العملية انطلاقًا من التعديلات المرصودة أو من دفق محتوى خام.

صُمِّمت القناة لتتبّع تسريبات المستندات الداخلية. وهي ليست إخفاءً للمعلومات بدرجة تصمد أمام الخصوم. قد تُدمَّر البيانات المُرمَّزة بالطباعة ثم المسح الضوئي، أو تحويل ⁨PDF⁩، أو إعادة الهيكلة الخطّية (re-linearization)، أو إعادة كتابة دفق المحتوى، أو أي عملية تُطبِّع التقنين. لا تملك ⁨NextPDF⁩ أي شهادة لهذه القناة ولا تمنح أيًّا منها. تذكر هذه الصفحة القدرة لا المطابقة.

تُشحن هذه القدرة ضمن ⁨NextPDF Enterprise⁩ (⁨nextpdf/enterprise⁩) وتُفعَّل بمظروف ترخيص من فئة ⁨Enterprise⁩. لا يُحمِّل أي نشرٍ يفتقر إلى ذلك الاستحقاق فئات هذه القدرة. قارِن الإصدارات واحصل على ترخيص.

سطح واجهة برمجة التطبيقات العامة

قسم بعنوان «سطح واجهة برمجة التطبيقات العامة»

تكشف القناة عن أربع فئات ⁨final⁩. جميع نقاط الدخول ⁨public static⁩، عدا مُنشئ ⁨SteganographyConfig⁩ ومُلحِق الوصول ⁨effectiveMaxOffset⁩ الخاص به. يُطلِق المُرمِّز الاستثناء المُساعد ⁨NextPDF\Enterprise\Security\Steganography\SteganographyEncryptionException⁩؛ وهو ليس نوعًا يُنشئه المُستدعي.

الرمزالمعاملاتالسلوك الافتراضييُعيديُطلِق أو يفشل بـملاحظات
SteganographyEncoder::encode$payload، $text، $fontKey، $metrics (FontMetrics$secretKey، $config (SteganographyConfig)‏⁨$payload⁩ فارغة تُعيد ⁨[]⁩؛ يتحقّق من قوة المفتاح؛ يُشفّر؛ يحسب إزاحات تقنين لكل موضع.array<int, float> (الموضع ⁨=>⁩ التعديل بوحدة ⁨1/1000 em⁩، وفق اصطلاح ⁨AFM⁩)InvalidArgumentException (مفتاح دون الحدّ الأدنى)؛ OverflowException (نص أقل من حرفين، أو حمولة تتجاوز السعة)؛ SteganographyEncryptionException (فشل ⁨AEAD⁩)مرِّر النتيجة إلى ⁨NextPDF\Content\TextRenderer::buildTjArrayOperator()⁩. تُعيد الواجهة تعديلات وفق اصطلاح ⁨AFM⁩؛ ويُجري ⁨buildTjArrayOperator()⁩ التحويل الرقمي إلى ⁨TJ⁩ في ⁨PDF⁩ (يطرح ⁨ISO 32000-2⁩ الرقم من الموضع الحالي). على كُتّاب دفق المحتوى اليدويين الحفاظ على اصطلاح الإشارة ذاك.
SteganographyEncoder::assertSecretKeyStrength$secretKeyيرفض مفتاحًا أقصر من الحدّ الأدنى.voidInvalidArgumentException (مفتاح دون الحدّ الأدنى)حارس مشترك لمسار الكتابة، مُنعكس على مسار القراءة.
SteganographyEncoder::MIN_SECRET_KEY_LENGTHثابتالحدّ الأدنى لطول المفتاح ⁨128-bit⁩ بالبايتات.int (16)غير منطبقتفرض المكتبة الطول لا الإنتروبيا.
SteganographyDecoder::decode$observedAdjustments، $text، $fontKey، $metrics (FontMetrics$secretKey، $config (SteganographyConfig)يتحقّق من قوة المفتاح؛ يُكمِّم الانحرافات؛ يُعيد بناء الكتلة (blob)؛ يفكّ التشفير بـ ⁨AEAD⁩.`stringnull(الحمولة، أوnull` عند مفتاح خاطئ أو عدم وجود حمولة)InvalidArgumentException (مفتاح دون الحدّ الأدنى)
SteganographyDecoder::decodeFromContentStream$contentStream، $fontKey، $metrics (FontMetrics$secretKey، $config (SteganographyConfig)يُجزّئ الدفق إلى رموز، ويعيد بناء النص والتعديلات من مصفوفات ⁨TJ⁩، ثم يفوّض إلى ⁨decode⁩.`stringnull(الحمولة، أوnullعند غياب نصTJ` أو فشل فكّ التشفير)InvalidArgumentException (مفتاح دون الحدّ الأدنى، عبر decode)
SteganographyConfig::__construct$bitDepth، $maxAdjustmentEmRatio، $cipher، $requirePdfACompatibilityيتحقّق من نطاق كل وسيط؛ يُنتج كائن قيمة غير قابل للتغيير.نسخة SteganographyConfigInvalidArgumentException (‏⁨$bitDepth⁩ أو ⁨$maxAdjustmentEmRatio⁩ أو ⁨$cipher⁩ غير صالح)فئة readonly؛ الوسائط الأربعة خصائص عامة مُرقّاة.
SteganographyConfig::effectiveMaxOffsetلا شيءيُعيد ⁨$maxAdjustmentEmRatio * 1000⁩، مقسومًا على اثنين عند طلب توافق ⁨PDF/A⁩.float (إزاحة بوحدة ⁨1/1000 em⁩)غير منطبقيقلّل القسمة على اثنين خطر اكتشاف عدم تطابق العرض.
SteganographyConfig::CRYPTO_OVERHEADثابتعبء التشفير الثابت لكل حمولة بالبايتات.int (32)غير منطبقطول ⁨4-byte⁩، و⁨nonce⁩ بحجم ⁨12-byte⁩، ووسم بحجم ⁨16-byte⁩.
SteganographyCapacity::calculate$text، $config (SteganographyConfig)يحسب بايتات الحمولة القابلة للاستخدام للنص، بعد العبء.int (‏⁨0⁩ عندما يكون النص قصيرًا جدًا)غير منطبقالسعة تساوي ⁨positions * bitDepth / 8⁩ ناقص العبء.
SteganographyCapacity::minimumTextLength$payloadBytes، $config (SteganographyConfig)يحسب أدنى عدد أحرف ⁨UTF-8⁩ لحمولة.int (عدد الأحرف)غير منطبقمعكوس calculate.

تلي التواقيع الحرفية، مع بيان مصدر كل منها.

public static function encode(
string $payload,
string $text,
string $fontKey,
FontMetrics $metrics,
string $secretKey,
SteganographyConfig $config = new SteganographyConfig(),
): array
public static function assertSecretKeyStrength(string $secretKey): void
public const int MIN_SECRET_KEY_LENGTH = 16;
public static function decode(
array $observedAdjustments,
string $text,
string $fontKey,
FontMetrics $metrics,
string $secretKey,
SteganographyConfig $config = new SteganographyConfig(),
): ?string
public static function decodeFromContentStream(
string $contentStream,
string $fontKey,
FontMetrics $metrics,
string $secretKey,
SteganographyConfig $config = new SteganographyConfig(),
): ?string
public function __construct(
public int $bitDepth = 1,
public float $maxAdjustmentEmRatio = 0.02,
public string $cipher = 'aes-256-gcm',
public bool $requirePdfACompatibility = false,
)
public function effectiveMaxOffset(): float
public const int CRYPTO_OVERHEAD = 32;
public static function calculate(
string $text,
SteganographyConfig $config = new SteganographyConfig(),
): int
public static function minimumTextLength(
int $payloadBytes,
SteganographyConfig $config = new SteganographyConfig(),
): int

يقسم المُرمِّز ⁨$text⁩ إلى أحرف ⁨UTF-8⁩ ويُكوّن موضعًا واحدًا لكل زوج أحرف متتالٍ. يحمل كل موضع ⁨$config->bitDepth⁩ من البتات، وهو واحد أو اثنان. تُشفَّر الحمولة أولًا، ثم تُسلسَل إلى كتلة (blob)، ثم تُحوَّل إلى تسلسل بتات. يُرمِّز كل موضع بتاته على شكل إزاحة صغيرة غير سالبة تُضاف إلى قيمة التقنين الطبيعية لذلك الزوج من الأحرف.

الإزاحة كسر من الإزاحة القصوى الفعّالة. الإزاحة القصوى الفعّالة هي ⁨$maxAdjustmentEmRatio * 1000⁩ وحدة تصميم، مقسومة على اثنين عندما يكون ⁨$requirePdfACompatibility⁩ صحيحًا. تُقرأ قيمة التقنين الطبيعية من ⁨$metrics⁩ عبر ⁨FontMetrics::getKernPair⁩. الخريطة المُعادة مُتناثرة: يُحذف أي موضع يكون تعديله النهائي صفرًا تمامًا.

يستخدم التشفير ⁨HKDF-SHA-256⁩ لاشتقاق مفتاح بحجم ⁨32-byte⁩. مِلح ⁨HKDF⁩ هو ⁨$fontKey⁩ غير السرّي، وعلامة المعلومات ثابت محدّد. لذا فإن ⁨$secretKey⁩ الخاص بالمُستدعي هو حدّ السرية الوحيد. خوارزمية ⁨AEAD⁩ هي ⁨aes-256-gcm⁩ أو ⁨chacha20-poly1305⁩، يُختار بها عبر ⁨$config->cipher⁩، وتُنفَّذ عبر ⁨openssl_encrypt⁩ مع ⁨nonce⁩ جديد بحجم ⁨12-byte⁩ ووسم بحجم ⁨16-byte⁩. الكتلة المُسلسَلة هي طول ⁨big-endian⁩ بحجم ⁨4-byte⁩، و⁨nonce⁩ بحجم ⁨12-byte⁩، والنص المُشفَّر، والوسم بحجم ⁨16-byte⁩؛ هذا العبء الثابت هو ⁨CRYPTO_OVERHEAD⁩، وهو ⁨32 بايت⁩.

يعكس المُفكِّك التحويل. يحسب انحراف كل تعديل مرصود عن التقنين الطبيعي، ويُطبّعه بالإزاحة القصوى الفعّالة، ويُكمِّمه إلى أقرب مستوى. يُعيد تجميع الكتلة، ويتحقّق من ترويسة الطول، ويستدعي ⁨openssl_decrypt⁩. يؤدي مفتاح خاطئ أو حمولة مفقودة أو تعديلات تالفة إلى فشل مصادقة ⁨AEAD⁩، فيُعيد المُفكِّك ⁨null⁩. يُجزّئ ⁨decodeFromContentStream⁩ الدفق الخام أولًا إلى رموز باستخدام ⁨NextPDF\Pro\Projection\ContentProjectionWriter::tokenize⁩، ويعيد بناء النص والتعديلات الرقمية من كل مصفوفة ⁨TJ⁩، ثم يفوّض إلى ⁨decode⁩.

يُبلّغ ⁨SteganographyCapacity::calculate⁩ عن حجم الحمولة القابل للاستخدام لنصٍ وإعدادٍ، بعد طرح ⁨CRYPTO_OVERHEAD⁩؛ ويُعيد صفرًا عندما يكون النص قصيرًا جدًا. و⁨SteganographyCapacity::minimumTextLength⁩ هو المعكوس: أصغر عدد أحرف ⁨UTF-8⁩ يسمح بحمولة بالحجم المطلوب.

الحالات الحدّية وأنماط الفشل

قسم بعنوان «الحالات الحدّية وأنماط الفشل»
  • ‏⁨$payload⁩ فارغة تُعيد خريطة فارغة من ⁨encode⁩؛ لا تُكتب أي بايتات، ولا يُبلَغ حارس قوة المفتاح.
  • بالنسبة لحمولة غير فارغة، يُطلق ⁨$text⁩ الذي يقلّ عن حرفين ⁨OverflowException⁩ في ⁨encode⁩ (الحمولة الفارغة تختصر إلى ⁨[]⁩ قبل فحص الطول)؛ وينتج عن النص ذاته ⁨null⁩ في ⁨decode⁩ وصفرٌ في ⁨SteganographyCapacity::calculate⁩.
  • ‏⁨$payload⁩ أكبر من سعة النص تُطلق ⁨OverflowException⁩ قبل إصدار أي تعديل.
  • ‏⁨$secretKey⁩ أقصر من ⁨MIN_SECRET_KEY_LENGTH⁩ (‏⁨16 بايت⁩) يُطلق ⁨InvalidArgumentException⁩ على مساري الكتابة والقراءة معًا. هذا انتهاك للعقد، يختلف عن إخفاق المفتاح الخاطئ العادي.
  • يؤدي مفتاح خاطئ أو مجموعة تعديلات تالفة أو كتلة مبتورة إلى إعادة ⁨decode⁩ للقيمة ⁨null⁩ عبر فشل مصادقة ⁨AEAD⁩، لا عبر استثناء.
  • تُعامَل المواضع الغائبة عن خريطة ⁨$observedAdjustments⁩ المتناثرة كانحراف صفري أثناء الاستخراج.
  • يُعيد ⁨decodeFromContentStream⁩ القيمة ⁨null⁩ عندما لا يحتوي الدفق على نص ⁨TJ⁩.
  • القناة هشّة بحكم التصميم. يمكن للطباعة ثم المسح الضوئي، أو تحويل ⁨PDF⁩، أو إعادة الهيكلة الخطّية، أو إعادة كتابة دفق المحتوى، أو تطبيع التقنين أن تُدمِّر البيانات المُرمَّزة. وهي غير مناسبة للاستخدام في مواجهة الخصوم أو للأرشفة.

تستخدم القناة ⁨HKDF-SHA-256⁩ لاشتقاق المفاتيح وخوارزمية ⁨AEAD⁩ واحدة للسرية والسلامة. لا تملك ⁨NextPDF⁩ أي تحقّق ⁨FIPS⁩ لهذه القناة ولا تدّعي شيئًا من ذلك. لا تفرض الوحدة ملفّ تعريف ⁨FIPS⁩؛ واختيار الخوارزمية قرار المُستدعي عبر ⁨$config->cipher⁩. إن ⁨aes-256-gcm⁩ هو ⁨AES⁩ في وضع ⁨Galois/Counter Mode⁩، وهو وضع تشفير مُصادَق مبنيّ على شيفرة كتلية ⁨128-bit⁩ مُعتمدة، ويُتحقَّق من مطابقتها ضمن ⁨CMVP⁩، وفق ⁨NIST SP 800-38D §2⁩. أمّا ⁨chacha20-poly1305⁩ فليس مُعرَّفًا في توصية أوضاع التشغيل الصادرة عن ⁨NIST⁩، ولذا يرفضه مزوّد ⁨OpenSSL⁩ المُقيَّد بـ ⁨FIPS⁩؛ فيُعيد ⁨openssl_encrypt⁩ حينها القيمة ⁨false⁩ ويُطلق المُرمِّز ⁨SteganographyEncryptionException⁩. وتحديد ما إذا كان أي نشرٍ يستوفي متطلّب ⁨FIPS⁩ هو من شأن المُشغّل مقابل مزوّده المُتحقَّق منه، لا تأكيدًا من ⁨NextPDF⁩.

يكتب التضمين عناصر رقمية داخل مصفوفة إظهار النص ⁨TJ⁩. وفق ⁨ISO 32000-2:2020 §9.4.3⁩، تُظهر مصفوفة ⁨TJ⁩ النص وتتيح لعنصر رقمي ضبط موضع المِحرف؛ ويُعبَّر عن الرقم بأجزاء من الألف من وحدة فضاء النص ويُطرح من الموضع الحالي. بعد رسم المِحرف، تُزاح مصفوفة النص بمقدار الإزاحة المُجمَّعة، فيُغيّر الرقم الموضعي مكان المحارف اللاحقة — ⁨ISO 32000-2:2020 §9.4.4⁩. تضيف القناة إزاحاتها إلى قيم التقنين الطبيعية وفق اصطلاح ⁨1/1000 em⁩ (‏⁨AFM⁩) ذاته، حيث تُضيّق القيمة السالبة التباعد.

يقتصر الأساس المرجعي لـ ⁨AEAD⁩ على اختيار البدائيات: يقابل ⁨aes-256-gcm⁩ وضع ⁨GCM⁩ في ⁨NIST SP 800-38D §2⁩. ذلك المرجع يُعرّف خوارزمية؛ وليس تحقّقًا من هذه القناة.

جميع البنود مُعاد صياغتها؛ ولا تُعيد ⁨NextPDF⁩ إنتاج النص المِعياري. لا تُقدّم ⁨NextPDF⁩ أي ادّعاء بشأن إخفاء المعلومات أو التعمية أو مطابقة ⁨PDF⁩ لهذه القناة. والمواءمة البنيوية مع نموذج تموضع ⁨TJ⁩ بيان قدرة لا شهادة. ويبقى الإفصاح عن المتانة قائمًا: القناة مخصّصة لتتبّع التسريبات الداخلية، وهي ليست بدرجة تصمد أمام الخصوم.

  • نقاط الدخول توابع ⁨public static⁩ في ⁨NextPDF\Enterprise\Security\Steganography⁩، عدا مُنشئ ⁨SteganographyConfig⁩ و⁨effectiveMaxOffset⁩.
  • ‏⁨SteganographyConfig⁩ كائن قيمة ⁨final readonly⁩. خصائصه الأربع غير قابلة للتغيير بعد الإنشاء، وتُتحقَّق نطاقات وسائطه في المُنشئ: ⁨$bitDepth⁩ إمّا ⁨1⁩ أو ⁨2⁩، و⁨$maxAdjustmentEmRatio⁩ ضمن ⁨(0, 0.05]⁩، و⁨$cipher⁩ إمّا ⁨aes-256-gcm⁩ أو ⁨chacha20-poly1305⁩.
  • يستهلك ⁨NextPDF\Content\TextRenderer::buildTjArrayOperator⁩ خرج ⁨encode⁩. وتأتي أزواج التقنين من ⁨NextPDF\Typography\FontMetrics⁩. ويقرأ فكّ تشفير دفق المحتوى عبر ⁨NextPDF\Pro\Projection\ContentProjectionWriter⁩ دون تعديل الدفق.
  • يُفرَض الحدّ الأدنى لطول المفتاح عند نقطة الدخول ويُعاد تأكيده عند حدّ التعمية الخاص، بحيث لا يمكن لأي مسار داخلي بلوغ ⁨HKDF⁩ بمفتاح ضعيف. تفرض المكتبة الطول لا الإنتروبيا؛ وتوفير مادة مفاتيح عالية الإنتروبيا مسؤولية المُدمِج.
  • ‏⁨CRYPTO_OVERHEAD⁩ (‏⁨32 بايت⁩) هو التكلفة الثابتة لكل حمولة، وقد طُرحت مسبقًا في ⁨SteganographyCapacity::calculate⁩.
  • قيمة ⁨since⁩ المُوثَّقة هي ⁨3.1.0⁩ لسطح ⁨Enterprise⁩ المُجمَّع. ويرث ⁨SteganographyEncryptionException⁩ من ⁨RuntimeException⁩، لذا تستمر مواقع الاستدعاء التي تلتقط النوع العام في العمل.

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