Enterprise edición
Esteganografía — Referencia detallada
En resumen
Sección titulada «En resumen»Esta referencia técnica documenta el canal esteganográfico de NextPDF Enterprise. El canal oculta una carga útil cifrada dentro de los ajustes numéricos de kerning de un arreglo de presentación de texto TJ. Cuenta con cuatro símbolos públicos: SteganographyEncoder, SteganographyDecoder, SteganographyConfig y SteganographyCapacity. El codificador deriva una clave con HKDF-SHA-256, cifra la carga útil con un cifrado AEAD y devuelve desplazamientos de kerning por posición. El decodificador invierte el proceso a partir de los ajustes observados o de un flujo de contenido en bruto.
El canal está diseñado para el rastreo interno de fugas de documentos. No es esteganografía de grado adversario. Los datos codificados pueden destruirse al imprimir y escanear, al convertir el PDF, al re-linealizar, al reescribir el flujo de contenido o mediante cualquier operación que normalice el kerning. NextPDF no posee ninguna certificación para este canal ni otorga ninguna. Esta página declara capacidad, no conformidad.
Disponibilidad y licencia
Sección titulada «Disponibilidad y licencia»Esta capacidad se distribuye en NextPDF Enterprise (nextpdf/enterprise) y se activa con un sobre de licencia de nivel Enterprise. Una implementación sin ese derecho no carga las clases de la capacidad. Compare ediciones y obtenga una licencia.
Superficie de la API pública
Sección titulada «Superficie de la API pública»El canal expone cuatro clases finales. Todos los puntos de entrada son public static, salvo el constructor de SteganographyConfig y su descriptor de acceso effectiveMaxOffset. La clase de apoyo NextPDF\Enterprise\Security\Steganography\SteganographyEncryptionException la lanza el codificador; no es un tipo que construya el llamador.
| Símbolo | Parámetros | Comportamiento predeterminado | Devuelve | Lanza o falla con | Notas |
|---|---|---|---|---|---|
SteganographyEncoder::encode | $payload, $text, $fontKey, $metrics (FontMetrics), $secretKey, $config (SteganographyConfig) | Un $payload vacío devuelve []; verifica la robustez de la clave; cifra; calcula los desplazamientos de kerning por posición. | array<int, float> (posición => ajuste en 1/1000 em, convención AFM) | InvalidArgumentException (clave por debajo del mínimo); OverflowException (texto de menos de 2 caracteres, o carga útil por encima de la capacidad); SteganographyEncryptionException (fallo del AEAD) | Pase el resultado a NextPDF\Content\TextRenderer::buildTjArrayOperator(). La API devuelve ajustes en convención AFM; buildTjArrayOperator() realiza la conversión numérica del TJ de PDF (ISO 32000-2 resta el número de la posición actual). Quienes escriban flujos de contenido manualmente deben preservar esa convención de signo. |
SteganographyEncoder::assertSecretKeyStrength | $secretKey | Rechaza una clave más corta que el mínimo. | void | InvalidArgumentException (clave por debajo del mínimo) | Protección compartida de la ruta de escritura, reflejada en la ruta de lectura. |
SteganographyEncoder::MIN_SECRET_KEY_LENGTH | constante | El mínimo de longitud de clave de 128 bits, en bytes. | int (16) | No aplicable | La biblioteca impone la longitud, no la entropía. |
SteganographyDecoder::decode | $observedAdjustments, $text, $fontKey, $metrics (FontMetrics), $secretKey, $config (SteganographyConfig) | Verifica la robustez de la clave; cuantiza las desviaciones; reconstruye el blob; descifra con AEAD. | `string | null(carga útil, onull` con clave incorrecta o sin carga útil) | InvalidArgumentException (clave por debajo del mínimo) |
SteganographyDecoder::decodeFromContentStream | $contentStream, $fontKey, $metrics (FontMetrics), $secretKey, $config (SteganographyConfig) | Tokeniza el flujo, reconstruye el texto y los ajustes a partir de los arreglos TJ y luego delega en decode. | `string | null(carga útil, onullcuando no hay textoTJ` o el descifrado falla) | InvalidArgumentException (clave por debajo del mínimo, vía decode) |
SteganographyConfig::__construct | $bitDepth, $maxAdjustmentEmRatio, $cipher, $requirePdfACompatibility | Valida el dominio de cada argumento; produce un objeto de valor inmutable. | Instancia de SteganographyConfig | InvalidArgumentException ($bitDepth, $maxAdjustmentEmRatio o $cipher no válidos) | Clase readonly; los cuatro argumentos son propiedades públicas promovidas. |
SteganographyConfig::effectiveMaxOffset | ninguno | Devuelve $maxAdjustmentEmRatio * 1000, reducido a la mitad cuando se solicita compatibilidad con PDF/A. | float (desplazamiento en 1/1000 em) | No aplicable | La reducción a la mitad disminuye el riesgo de detección por discordancia de anchura. |
SteganographyConfig::CRYPTO_OVERHEAD | constante | El sobrecoste fijo de cifrado por carga útil, en bytes. | int (32) | No aplicable | 4 bytes de longitud, 12 bytes de nonce, 16 bytes de etiqueta. |
SteganographyCapacity::calculate | $text, $config (SteganographyConfig) | Calcula los bytes de carga útil aprovechables para el texto, tras el sobrecoste. | int (0 cuando el texto es demasiado corto) | No aplicable | La capacidad es positions * bitDepth / 8 menos el sobrecoste. |
SteganographyCapacity::minimumTextLength | $payloadBytes, $config (SteganographyConfig) | Calcula el recuento mínimo de caracteres UTF-8 para una carga útil. | int (recuento de caracteres) | No aplicable | Inverso de calculate. |
Las firmas textuales se muestran a continuación, cada una con su procedencia en el código fuente.
public static function encode( string $payload, string $text, string $fontKey, FontMetrics $metrics, string $secretKey, SteganographyConfig $config = new SteganographyConfig(),): arraypublic static function assertSecretKeyStrength(string $secretKey): voidpublic 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(),): ?stringpublic static function decodeFromContentStream( string $contentStream, string $fontKey, FontMetrics $metrics, string $secretKey, SteganographyConfig $config = new SteganographyConfig(),): ?stringpublic function __construct( public int $bitDepth = 1, public float $maxAdjustmentEmRatio = 0.02, public string $cipher = 'aes-256-gcm', public bool $requirePdfACompatibility = false,)public function effectiveMaxOffset(): floatpublic const int CRYPTO_OVERHEAD = 32;public static function calculate( string $text, SteganographyConfig $config = new SteganographyConfig(),): intpublic static function minimumTextLength( int $payloadBytes, SteganographyConfig $config = new SteganographyConfig(),): intContrato de comportamiento
Sección titulada «Contrato de comportamiento»El codificador divide $text en caracteres UTF-8 y forma una posición por cada par de caracteres consecutivos. Cada posición transporta $config->bitDepth bits, que son uno o dos. La carga útil se cifra primero, luego se serializa en un blob y después se convierte en una secuencia de bits. Cada posición codifica sus bits como un pequeño desplazamiento no negativo que se añade al valor de kerning natural de ese par de caracteres.
El desplazamiento es una fracción del desplazamiento máximo efectivo. El desplazamiento máximo efectivo es $maxAdjustmentEmRatio * 1000 unidades de diseño, reducido a la mitad cuando $requirePdfACompatibility es verdadero. El kerning natural se lee de $metrics a través de FontMetrics::getKernPair. El mapa devuelto es disperso: se omite toda posición cuyo ajuste final sea exactamente cero.
El cifrado utiliza HKDF-SHA-256 para derivar una clave de 32 bytes. La sal de HKDF es el $fontKey no secreto y la etiqueta de información es una constante fija. Por lo tanto, el $secretKey del llamador es el único límite de confidencialidad. El cifrado AEAD es aes-256-gcm o chacha20-poly1305, seleccionado por $config->cipher, ejecutado a través de openssl_encrypt con un nonce nuevo de 12 bytes y una etiqueta de 16 bytes. El blob serializado consta de una longitud big-endian de 4 bytes, el nonce de 12 bytes, el texto cifrado y la etiqueta de 16 bytes; este sobrecoste fijo es CRYPTO_OVERHEAD, es decir, 32 bytes.
El decodificador invierte la transformación. Calcula la desviación de cada ajuste observado respecto del kerning natural, la normaliza según el desplazamiento máximo efectivo y la cuantiza al nivel más cercano. Reensambla el blob, valida la cabecera de longitud y llama a openssl_decrypt. Una clave incorrecta, una carga útil ausente o unos ajustes corruptos hacen que la autenticación AEAD falle, y el decodificador devuelve null. decodeFromContentStream primero tokeniza el flujo en bruto con NextPDF\Pro\Projection\ContentProjectionWriter::tokenize, reconstruye el texto y los ajustes numéricos de cada arreglo TJ, y luego delega en decode.
SteganographyCapacity::calculate informa del tamaño de carga útil aprovechable para un texto y una configuración, tras restar CRYPTO_OVERHEAD; devuelve cero cuando el texto es demasiado corto. SteganographyCapacity::minimumTextLength es el inverso: el menor recuento de caracteres UTF-8 que admite una carga útil del tamaño solicitado.
Casos límite y modos de fallo
Sección titulada «Casos límite y modos de fallo»- Un
$payloadvacío devuelve un mapa vacío desdeencode; no se escribe ningún byte, y no se alcanza la protección de robustez de la clave. - Para una carga útil no vacía, un
$textcon menos de dos caracteres provocaOverflowExceptionenencode(una carga útil vacía se cortocircuita a[]antes de la comprobación de longitud); el mismo texto producenullendecodey cero enSteganographyCapacity::calculate. - Un
$payloadmayor que la capacidad del texto provocaOverflowExceptionantes de que se emita ningún ajuste. - Un
$secretKeymás corto queMIN_SECRET_KEY_LENGTH(16 bytes) provocaInvalidArgumentExceptiontanto en la ruta de escritura como en la de lectura. Esto es una violación de contrato, distinta de un fallo normal por clave incorrecta. - Una clave incorrecta, un conjunto de ajustes corrupto o un blob truncado hacen que
decodedevuelvanullpor fallo de autenticación AEAD, no una excepción. - Las posiciones ausentes de un mapa
$observedAdjustmentsdisperso se tratan como una desviación de cero durante la extracción. decodeFromContentStreamdevuelvenullcuando el flujo no contiene textoTJ.- El canal es frágil por diseño. Imprimir y escanear, convertir el PDF, re-linealizar, reescribir el flujo de contenido o normalizar el kerning pueden destruir los datos codificados. No es apto para uso adversario ni de archivo.
Comportamiento en modo FIPS
Sección titulada «Comportamiento en modo FIPS»El canal usa HKDF-SHA-256 para la derivación de claves y un único cifrado AEAD para la confidencialidad y la integridad. NextPDF no posee ninguna validación FIPS para este canal ni reclama ninguna. El módulo no impone un perfil FIPS; la selección del cifrado es decisión del llamador a través de $config->cipher. aes-256-gcm es AES en modo Galois/Counter, un modo de cifrado autenticado basado en un cifrado de bloque de 128 bits aprobado cuya conformidad se valida bajo el CMVP, según NIST SP 800-38D §2. chacha20-poly1305 no está definido por una recomendación de modo de operación de NIST, por lo que un proveedor de OpenSSL restringido a FIPS lo rechaza; openssl_encrypt devuelve entonces false y el codificador lanza SteganographyEncryptionException. Que una implementación cumpla un requisito FIPS es una determinación del operador frente a su proveedor validado, no una afirmación de NextPDF.
Conformidad
Sección titulada «Conformidad»La incrustación escribe elementos numéricos en un arreglo de presentación de texto TJ. Según ISO 32000-2:2020 §9.4.3, un arreglo TJ muestra texto y permite que un elemento numérico ajuste la posición del glifo; el número se expresa en milésimas de una unidad de espacio de texto y se resta de la posición actual. Después de pintar un glifo, la matriz de texto se traslada según el desplazamiento combinado, de modo que un número de posicionamiento desplaza la ubicación de los glifos subsiguientes — ISO 32000-2:2020 §9.4.4. El canal añade sus desplazamientos a los valores de kerning natural en la misma convención de 1/1000 em (AFM), donde un valor negativo ajusta más el espaciado.
El fundamento del AEAD se limita a la selección de la primitiva: aes-256-gcm corresponde al modo GCM de NIST SP 800-38D §2. Esa referencia identifica un algoritmo; no es una validación de este canal.
Todas las cláusulas están parafraseadas; NextPDF no reproduce texto normativo. NextPDF no formula ninguna afirmación de conformidad esteganográfica, criptográfica ni de PDF para este canal. La alineación estructural con el modelo de posicionamiento TJ es una declaración de capacidad, no una certificación. La divulgación sobre robustez se mantiene: el canal es para el rastreo interno de fugas y no es de grado adversario.
Notas de desarrollo
Sección titulada «Notas de desarrollo»- Los puntos de entrada son métodos
public staticenNextPDF\Enterprise\Security\Steganography, salvo el constructor deSteganographyConfigyeffectiveMaxOffset. SteganographyConfiges un objeto de valorfinal readonly. Sus cuatro propiedades son inmutables tras la construcción, y los dominios de sus argumentos se validan en el constructor:$bitDepthes 1 o 2,$maxAdjustmentEmRatioestá en(0, 0.05], y$cipheresaes-256-gcmochacha20-poly1305.- La salida de encode la consume
NextPDF\Content\TextRenderer::buildTjArrayOperator. Los pares de kerning provienen deNextPDF\Typography\FontMetrics. La decodificación del flujo de contenido lee a través deNextPDF\Pro\Projection\ContentProjectionWritery no muta el flujo. - El mínimo de longitud de clave se impone en el punto de entrada y se vuelve a verificar en el límite criptográfico privado, de modo que ninguna ruta interna puede llegar a HKDF con una clave débil. La biblioteca impone la longitud, no la entropía; suministrar material de clave de alta entropía es responsabilidad del integrador.
CRYPTO_OVERHEAD(32 bytes) es el coste fijo por carga útil y ya lo restaSteganographyCapacity::calculate.- El
sincedocumentado es3.1.0para la superficie agregada de Enterprise.SteganographyEncryptionExceptionextiendeRuntimeException, de modo que los sitios de llamada que capturan el tipo genérico de runtime siguen funcionando.
Véase también
Sección titulada «Véase también»- Esteganografía (página de capacidad) — la descripción orientada a tareas del canal de rastreo de fugas.
- Seguridad — Referencia técnica — la superficie hermana de seguridad de Enterprise.
- Licencia y activación — cómo se aplica el sobre de licencia de Enterprise.
Límite de publicación
Sección titulada «Límite de publicación»Esta página documenta únicamente el comportamiento observable externamente y la superficie de API pública admitida. Las rutas de espacio de nombres internas, las clases auxiliares, las tablas de mecanismos, los nombres de archivo de runbooks y los prefijos de ticket quedan fuera de alcance.