Cuando entro en la línea de comando openssl dhparam -text 1024
, el resultado de Safe-Prime es 1032 bits en lugar de 1024 bits. Parece que el primer byte siempre es 0. ¿Por qué es esto?
Prueba esto:
openssl genrsa | openssl rsa -text
Mira cada uno de los campos; Los primos, los exponentes, todos ellos. Ahora intenta de nuevo, y de nuevo, y de nuevo. Notará cierta incoherencia en cuanto a la presencia de un byte cero inicial. A veces lo es, a veces no lo es. El patrón es el siguiente: si se establece el primer bit del primer byte "real", es decir, si el primer carácter hexadecimal es menor que 8, no se mostrará (o almacenará) un cero inicial, pero si es 8 o superior, entonces se agregará un byte cero.
Esto deja bastante claro que el problema que están resolviendo es la interpretación de signos. Con los valores firmados, el primer bit es el signo del número; agregar un cero inicial elimina cualquier ambigüedad.
Para ver lo que realmente está almacenado (no se muestra) mira esto:
openssl genrsa | openssl asn1parse
Verá que, mientras que solo se muestran 64 o 32 bytes, verá l= 33
o l= 65
que indica que realmente se almacena un byte adicional. Ese es el byte inicial cero que viste anteriormente.
En cuanto a las claves DH de 32 bits, mira esto:
$ openssl dhparam 32 -text
Generating DH parameters, 32 bit long safe prime, generator 2
This is going to take a long time
PKCS#3 DH Parameters: (32 bit)
prime: 2714658203 (0xa1ce659b)
generator: 2 (0x2)
Por lo tanto, parece que solo hay 4 bytes a pesar de que el bit inicial está establecido. Pero echemos un vistazo a la asn1parse:
0:d=0 hl=2 l= 10 cons: SEQUENCE
2:d=1 hl=2 l= 5 prim: INTEGER :A1CE659B
9:d=1 hl=2 l= 1 prim: INTEGER :02
Por lo tanto, para este primer de 32 bits, se almacenan 5 bytes aunque solo se vieran 4 bytes.
La razón por la que no vió el byte cero esta vez es que como el valor almacenado es solo de 32 bits, se puede mostrar como un entero sin signo simple, y por lo tanto la biblioteca de visualización de OpenSSL corresponde le muestra el valor decimal y el valor hexadecimal en parens en lugar de mostrarle solo una cadena de bytes hexadecimales separados por dos puntos. Pero el cero inicial sigue ahí, como vimos en la salida de asn1.
Usted realmente obtiene una prima de 1024 bits: una prima de 1024 bits es un número entero cuyo valor es mayor que 2 1023 pero menor que 2 1024 . Eso es lo que te devuelve OpenSSL. Sin embargo, cuando se trata de almacenar ese entero en un archivo, se debe utilizar alguna convención de codificación para convertir ese entero en bytes. OpenSSL utiliza ASN.1 con el DER ( Reglas de codificación distinguida ).
En ASN.1, el tipo es INTEGER
, que es un valor entero genérico que podría ser negativo. Las reglas DER establecen que el INTEGER
se codificará como una etiqueta ( 02
, la etiqueta estándar para INTEGER
) luego una longitud ( 81 81
, que significa "129": el valor será una secuencia de 129 bytes) , luego el valor en sí, con big-endian firmó la interpretación . La palabra importante aquí es "firmado": ya que INTEGER
podría ser negativo, pero su primo es positivo, su codificación debe comenzar con un poco de valor 0. Si el primo se codificó exactamente 128 bytes, el primer bit del primer byte sería un 1 y el INTEGER
se consideraría negativo. Por lo tanto, se agrega un byte adicional 00
(según las reglas DER, el código debe tener una longitud mínima siempre que el primer bit coincida con el signo esperado, por lo que solo se puede agregar un solo byte 00
). La longitud total, con el encabezado, es de 132 bytes. El entero matemático que, por lo tanto, se codifica sigue siendo un número primo de 1024 bits, no un entero de 1032 bits o de 1056 bits.
Lea otras preguntas en las etiquetas encryption openssl