codificación de NULL opcional en DER

4

En PKCS1 hay DigestInfo:

  DigestInfo ::= SEQUENCE {
      digestAlgorithm AlgorithmIdentifier,
      digest OCTET STRING
  }

AlgorithmIdentifier se define en RFC5280 :

   AlgorithmIdentifier  ::=  SEQUENCE  {
        algorithm               OBJECT IDENTIFIER,
        parameters              ANY DEFINED BY algorithm OPTIONAL  }

PKCS1 proporciona codificaciones DER de DigestInfo para varios algoritmos de hash en página 43 :

   1. For the six hash functions mentioned in Appendix B.1, the DER
      encoding T of the DigestInfo value is equal to the following:

      MD2:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 02 05 00 04
                   10 || H.
      MD5:     (0x)30 20 30 0c 06 08 2a 86 48 86 f7 0d 02 05 05 00 04
                   10 || H.
      SHA-1:   (0x)30 21 30 09 06 05 2b 0e 03 02 1a 05 00 04 14 || H.
      SHA-256: (0x)30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00
                   04 20 || H.
      SHA-384: (0x)30 41 30 0d 06 09 60 86 48 01 65 03 04 02 02 05 00
                   04 30 || H.
      SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00
                      04 40 || H.

Si creo don1parse en una de esas codificaciones DER (sha512) obtengo lo siguiente:

    0:d=0  hl=2 l=  81 cons: SEQUENCE
    2:d=1  hl=2 l=  13 cons:  SEQUENCE
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha512
   15:d=2  hl=2 l=   0 prim:   NULL
   17:d=1  hl=2 l=  64 prim:  OCTET STRING
El algoritmo

se denota por OBJECT y los parámetros se denotan por NULL. Mi pregunta es ...

Si los parámetros son opcionales, ¿por qué NULL está presente? ¿Por qué las cadenas proporcionadas en PKCS1 corresponden a la codificación DER anterior en lugar de, digamos, esta (sin el NULL) ?:

    0:d=0  hl=2 l=  79 cons: SEQUENCE
    2:d=1  hl=2 l=  11 cons:  SEQUENCE
    4:d=2  hl=2 l=   9 prim:   OBJECT            :sha512
   15:d=1  hl=2 l=  64 prim:  OCTET STRING
    
pregunta neubert 12.01.2016 - 05:32
fuente

1 respuesta

2

La información en los dos RFC citados parece un poco contradictoria con respecto al algoritmo NULL después del algoritmo.

La definición general de la estructura afirma que el atributo de parámetros es opcional, sin embargo, en el apéndice con respecto al algoritmo rsaEncryption específicamente hay esto:

-- When rsaEncryption is used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.

Y algoritmos de hashing específicos similares:

-- When the following OIDs are used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.
--
md2WithRSAEncryption       OBJECT IDENTIFIER ::= { pkcs-1 2 }
md5WithRSAEncryption       OBJECT IDENTIFIER ::= { pkcs-1 4 }
sha1WithRSAEncryption      OBJECT IDENTIFIER ::= { pkcs-1 5 }
sha256WithRSAEncryption    OBJECT IDENTIFIER ::= { pkcs-1 11 }
sha384WithRSAEncryption    OBJECT IDENTIFIER ::= { pkcs-1 12 }
sha512WithRSAEncryption    OBJECT IDENTIFIER ::= { pkcs-1 13 }

Parece un poco tonto definir un campo como opcional, pero luego exige su presencia y valor. Tal vez hay otros algoritmos en los que se puede omitir el campo, pero estos algoritmos lo requieren específicamente.

El estándar parece confundirse en la sección EMSA-PKCS1-v1_5, donde habla sobre parámetros opcionales con algunos algoritmos:

-- When id-md2 and id-md5 are used in an AlgorithmIdentifier the
-- parameters MUST be present and MUST be NULL.

-- When id-sha1, id-sha256, id-sha384 and id-sha512 are used in an
-- AlgorithmIdentifier the parameters (which are optional) SHOULD
-- be omitted. However, an implementation MUST also accept
-- AlgorithmIdentifier values where the parameters are NULL.

Pero el ejemplo que sigue a este texto incluye el nulo:

sha1    HashAlgorithm ::= {
    algorithm   id-sha1,
    parameters  SHA1Parameters : NULL  -- included for compatibility
                                       -- with existing implementations
}

Todos los ejemplos de ASN.1 que miré en la documentación parecen incluir el nulo opcional obligatorio. Basado en el comportamiento de openssl (creación) y Mozilla PKIX (validación: enlace ) los nulos después de El algoritmo parece ser la interpretación generalmente aceptada de la documentación, aunque su presencia requerida podría argumentarse en función de la definición de la estructura original y la nula no parece agregar valor.

Actualización: encontré una publicación en la lista de correo de OpenSSL enlace que en realidad analiza este mismo problema, y la lógica de interpretación parece resumirse (con algo de historia) de la siguiente manera:

... declaring that in this particular case (optional parameters of
AlgorithmIdentifier) NULL is equivalent to (the same as) absent. In fact,
RFC 5754 (page 4) states that the correct encoding is omitting the empty
list altogether, but some uses defined their encoding as NULL, and it’s OK. 
It reveals some history of this duality:

The two alternatives arise from the loss of the OPTIONAL associated with the
algorithm identifier parameters when the 1988 syntax for
AlgorithmIdentifier was translated into the 1997 syntax.  Later, the
OPTIONAL was recovered via a defect report, but by then many people
thought that algorithm parameters were mandatory.  Because of this
history, some implementations encode parameters as a NULL element
while others omit them entirely.
    
respondido por el metaclassing 12.01.2016 - 21:10
fuente

Lea otras preguntas en las etiquetas