Saltar al contenido

¿Cómo codifica ASN.1 un identificador de objeto?

Tenemos la mejor información que hallamos en línea. Nosotros deseamos que te resulte de utilidad y si quieres compartir alguna mejora hazlo libremente.

Solución:

Sí, el OID está codificado en datos binarios. El OID 1.3.6.1.5.5.7.48.1 que mencionas se convierte en 2b 06 01 05 05 07 30 01 (los dos primeros números están codificados en un solo byte, todos los números restantes también están codificados en un solo byte porque son todos menor que 128).

Aquí encontrará una buena descripción de la codificación OID.

Pero la mejor manera de analizar sus datos ASN.1 es pegarlos en un decodificador en línea, por ejemplo, http://lapo.it/asn1js/.

Si todos sus dígitos son menores o iguales a 127, entonces está muy afortunado porque se pueden representar con un solo octeto cada uno. La parte complicada es cuando tiene números más grandes que son comunes, como 1.2.840.113549.1.1.5 (sha1WithRsaEncryption). Estos ejemplos se centran en la decodificación, pero la codificación es todo lo contrario.

1. Los primeros dos ‘dígitos’ se representan con un solo byte

Puede decodificar leyendo el primer byte en un número entero

var firstByteNumber = 42;
var firstDigit = firstByteNumber / 40;
var secondDigit = firstByteNumber % 40;

Produce los valores

1.2

2. Los bytes subsiguientes se representan mediante Cantidad de longitud variable, también denominada base 128.

VLQ tiene dos formas,

Forma corta: si el octeto comienza con 0, simplemente se representa con los 7 bits restantes.

Forma larga: si el octeto comienza con un 1 (el bit más significativo), combine los siguientes 7 bits de ese octeto más los 7 bits de cada octeto subsiguiente hasta que encuentre un octeto con un 0 como el bit más significativo (esto marca el último octeto).

El valor 840 se representaría con los siguientes dos bytes,

10000110
01001000

Combine to 00001101001000 and read as int.

Gran recurso para la codificación BER, http://luca.ntop.org/Teaching/Appunti/asn1.html

El primer octeto tiene valor 40 * valor1 + valor2. (Esto no es ambiguo, ya que value1 está limitado a los valores 0, 1 y 2; value2 está limitado al rango de 0 a 39 cuando value1 es 0 o 1; y, de acuerdo con X.208, n es siempre al menos 2.)

Los siguientes octetos, si los hay, codifican value3, …, valuen. Cada valor se codifica en base 128, el dígito más significativo primero, con la menor cantidad de dígitos posible, y el bit más significativo de cada octeto excepto el último en la codificación del valor establecido en “1”. Ejemplo: el primer octeto de la codificación BER del identificador de objeto de RSA Data Security, Inc. es 40 * 1 + 2 = 42 = 2a16. La codificación de 840 = 6 * 128 + 4816 es 86 48 y la codificación de 113549 = 6 * 1282 + 7716 * 128 + d16 es 86 f7 0d. Esto conduce a la siguiente codificación BER:

06 06 2a 86 48 86 f7 0d


Finalmente, aquí hay un decodificador OID que acabo de escribir en Perl.

sub getOid 
    my $bytes = shift;

    #first 2 nodes are 'special';
    use integer;
    my $firstByte = shift @$bytes;
    my $number = unpack "C", $firstByte;
    my $nodeFirst = $number / 40;
    my $nodeSecond = $number % 40;

    my @oidDigits = ($nodeFirst, $nodeSecond);

    while (@$bytes) 
        my $num = convertFromVLQ($bytes);
        push @oidDigits, $num;
    

    return join '.', @oidDigits;


sub convertFromVLQ 
    my $bytes = shift;

    my $firstByte = shift @$bytes;
    my $bitString = unpack "B*", $firstByte;

    my $firstBit = substr $bitString, 0, 1;
    my $remainingBits = substr $bitString, 1, 7;

    my $remainingByte = pack "B*", '0' . $remainingBits;
    my $remainingInt = unpack "C", $remainingByte;

    if ($firstBit eq '0') 
        return $remainingInt;
    
    else 
        my $bitBuilder = $remainingBits;

        my $nextFirstBit = "1";
        while ($nextFirstBit eq "1") 
            my $nextByte = shift @$bytes;
            my $nextBits = unpack "B*", $nextByte;

            $nextFirstBit = substr $nextBits, 0, 1;
            my $nextSevenBits = substr $nextBits, 1, 7;

            $bitBuilder .= $nextSevenBits;
        

        my $MAX_BITS = 32;
        my $missingBits = $MAX_BITS - (length $bitBuilder);
        my $padding = 0 x $missingBits;
        $bitBuilder = $padding . $bitBuilder;

        my $finalByte = pack "B*", $bitBuilder;
        my $finalNumber = unpack "N", $finalByte;
        return $finalNumber;
    


Codificación OID para tontos :):

  • cada componente OID está codificado en uno o más bytes (octetos)
  • La codificación OID es solo una concatenación de estas codificaciones de componentes OID
  • los dos primeros componentes están codificados de una manera especial (ver más abajo)
  • si el valor binario del componente OID tiene menos de 7 bits, la codificación es solo un octeto único, manteniendo el valor del componente (nota, el bit más significativo, más a la izquierda, siempre será 0)
  • de lo contrario, si tiene 8 bits o más, el valor se “distribuye” en varios octetos: divida la representación binaria en fragmentos de 7 bits (desde la derecha), rellene a la izquierda el primero con ceros si es necesario y forme octetos a partir de estos septetos agregando el bit 1 más significativo (izquierda), excepto desde el último fragmento, que tendrá el bit 0 allí.
  • los dos primeros componentes (XY) se codifican como si fueran un solo componente con un valor 40 * X + Y

Esta es una nueva redacción de la recomendación del UIT-T X.690, capítulo 8.19

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *