No estoy seguro de por qué quieres cortar bytes. Así que no estoy seguro de que esta sea una buena respuesta a su pregunta. De todos modos, vaya.
Esto es lo que descubrí al leer los RFC / experimentación.
How can I adjust the size of the private to 32 Bytes and public key to 64 Bytes?
No tienes que hacerlo. Ya están en esa forma. Es un poco confuso leerlo desde la impresión de openssl.
Does the leading 00 change the value of the number?
La respuesta es "No" si, de todos modos, ibas a analizarlo como int sin firmar. (Y "sí" si (por error) iba a analizarlo como un int firmado. En ese caso, debe mantener el prefijo 0x00).
TLDR : el 0x00 principal es un SIGN BYTE que openssl agrega solo para la impresión. NO está codificado en el propio certificado. Y supongo que puede cortar el byte principal (uno de 0x02, 0x03 o 0x04 ) de la tecla de menú porque solo almacena información sobre si se utiliza la codificación comprimida o no comprimida.
Clave de ejemplo con nullbyte inicial
Aquí hay un ejemplo de una clave aleatoria que generé:
$ cat leading-nullbyte.pem
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIN/37NFyCvL7brp4zljP83sNj1PvtFsp8dMR86EDwLZUoAoGCCqGSM49
AwEHoUQDQgAEK0acP7Ml6fgKy35YE7JGVP7AmNy7oJ6gl4QIqiwiSExbr4iDPfxT
81550HxXoiQiBJXBJxhgXYpIcJVmFGk20w==
-----END EC PRIVATE KEY-----
impresión ec leading_nullbyte.pem
Esta clave se muestra con el prefijo "00:" para la clave privada.
Al menos al usar la impresora openssl pretty ...
$ openssl ec -noout -text -in leading-nullbyte.pem
read EC key
Private-Key: (256 bit)
priv:
00:df:f7:ec:d1:72:0a:f2:fb:6e:ba:78:ce:58:cf:
f3:7b:0d:8f:53:ef:b4:5b:29:f1:d3:11:f3:a1:03:
c0:b6:54
pub:
04:2b:46:9c:3f:b3:25:e9:f8:0a:cb:7e:58:13:b2:
46:54:fe:c0:98:dc:bb:a0:9e:a0:97:84:08:aa:2c:
22:48:4c:5b:af:88:83:3d:fc:53:f3:5e:79:d0:7c:
57:a2:24:22:04:95:c1:27:18:60:5d:8a:48:70:95:
66:14:69:36:d3
ASN1 OID: prime256v1
NIST CURVE: P-256
asn1parse leading-nullbyte.pem
... sin embargo, al mirar dentro de la codificación ASN1 no hay un prefijo 00:
. Simplemente comienza con df:
de inmediato. Y también: la longitud se da como 32 ( l= 32
). No 33.
5:d=1 hl=2 l= 32 prim: OCTET STRING
0000 - df f7 ec d1 72 0a f2 fb-6e ba 78 ce 58 cf f3 7b ....r...n.x.X..{
Aquí están esas líneas en contexto:
$ openssl asn1parse -i -dump -in leading-nullbyte.pem
0:d=0 hl=2 l= 119 cons: SEQUENCE
2:d=1 hl=2 l= 1 prim: INTEGER :01
5:d=1 hl=2 l= 32 prim: OCTET STRING
0000 - df f7 ec d1 72 0a f2 fb-6e ba 78 ce 58 cf f3 7b ....r...n.x.X..{
0010 - 0d 8f 53 ef b4 5b 29 f1-d3 11 f3 a1 03 c0 b6 54 ..S..[)........T
39:d=1 hl=2 l= 10 cons: cont [ 0 ]
41:d=2 hl=2 l= 8 prim: OBJECT :prime256v1
51:d=1 hl=2 l= 68 cons: cont [ 1 ]
53:d=2 hl=2 l= 66 prim: BIT STRING
0000 - 00 04 2b 46 9c 3f b3 25-e9 f8 0a cb 7e 58 13 b2 ..+F.?.%....~X..
0010 - 46 54 fe c0 98 dc bb a0-9e a0 97 84 08 aa 2c 22 FT............,"
0020 - 48 4c 5b af 88 83 3d fc-53 f3 5e 79 d0 7c 57 a2 HL[...=.S.^y.|W.
0030 - 24 22 04 95 c1 27 18 60-5d 8a 48 70 95 66 14 69 $"...'.'].Hp.f.i
0040 - 36 d3 6.
Por lo tanto, el 0x00 inicial no está realmente codificado en el archivo de certificado. Aunque no he echado un vistazo al código fuente de openssl, me refiero a llamar a esto un error de impresión.
De acuerdo con RFC5915 (creo) una clave EC es un entero sin signo.
Clave de ejemplo SIN nullbyte inicial
Aquí hay otra clave aleatoria que generé. NO tiene el prefijo 0x00 cuando se usa la impresora openssl ec pretty.
Así que esto me dice que ese prefijo 0x00 no está necesariamente allí para cada clave privada de EC.
$ cat no-leading-nullbyte.pem
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIAGcFoPfqfFZ5TDv71ZBBCctapiVKwZikE8HfKf61V1DoAoGCCqGSM49
AwEHoUQDQgAENPjKv9vobJnz1FSlSu5cNPyPwCvcsMmIr5HH92C+mZdVtanHwlTm
29IwOE5lSE8KMywIJs8pLCvX79kJhZ/upg==
-----END EC PRIVATE KEY-----
impresión ec no-leading-nullbyte.pem
$ openssl ec -noout -text -in no-leading-nullbyte.pem
read EC key
Private-Key: (256 bit)
priv:
01:9c:16:83:df:a9:f1:59:e5:30:ef:ef:56:41:04:
27:2d:6a:98:95:2b:06:62:90:4f:07:7c:a7:fa:d5:
5d:43
pub:
04:34:f8:ca:bf:db:e8:6c:99:f3:d4:54:a5:4a:ee:
5c:34:fc:8f:c0:2b:dc:b0:c9:88:af:91:c7:f7:60:
be:99:97:55:b5:a9:c7:c2:54:e6:db:d2:30:38:4e:
65:48:4f:0a:33:2c:08:26:cf:29:2c:2b:d7:ef:d9:
09:85:9f:ee:a6
ASN1 OID: prime256v1
NIST CURVE: P-256
asn1parse no-leading-nullbyte.pem
Aquí nuevamente la longitud se da como 32:
5:d=1 hl=2 l= 32 prim: OCTET STRING
0000 - 01 9c 16 83 df a9 f1 59-e5 30 ef ef 56 41 04 27 .......Y.0..VA.'
análisis completo:
$ openssl asn1parse -i -dump -in no-leading-nullbyte.pem
0:d=0 hl=2 l= 119 cons: SEQUENCE
2:d=1 hl=2 l= 1 prim: INTEGER :01
5:d=1 hl=2 l= 32 prim: OCTET STRING
0000 - 01 9c 16 83 df a9 f1 59-e5 30 ef ef 56 41 04 27 .......Y.0..VA.'
0010 - 2d 6a 98 95 2b 06 62 90-4f 07 7c a7 fa d5 5d 43 -j..+.b.O.|...]C
39:d=1 hl=2 l= 10 cons: cont [ 0 ]
41:d=2 hl=2 l= 8 prim: OBJECT :prime256v1
51:d=1 hl=2 l= 68 cons: cont [ 1 ]
53:d=2 hl=2 l= 66 prim: BIT STRING
0000 - 00 04 34 f8 ca bf db e8-6c 99 f3 d4 54 a5 4a ee ..4.....l...T.J.
0010 - 5c 34 fc 8f c0 2b dc b0-c9 88 af 91 c7 f7 60 be ...+........'.
0020 - 99 97 55 b5 a9 c7 c2 54-e6 db d2 30 38 4e 65 48 ..U....T...08NeH
0030 - 4f 0a 33 2c 08 26 cf 29-2c 2b d7 ef d9 09 85 9f O.3,.&.),+......
0040 - ee a6 ..
Extra: ¿Cómo sé que el 0x00 es un byte de signo?
... por experimentación:
He generado mil claves así:
$ for i in $(seq -w 1000); do echo $i; openssl ecparam -name prime256v1 -genkey -noout > key.$i.pem; done
Y luego los ordené y los conté por el primer byte así:
$ for i in $(seq -w 1000); do openssl ec -noout -text -in key.$i.pem 2>/dev/null | grep '^priv:' -A1 | tail -1; done | sed 's/ *//' | sed 's/\(..\).*//' | sort | uniq -c
496 00
3 01
3 02
4 03
5 04
4 05
5 06
3 07
1 08
3 09
1 0a
3 0b
2 0c
2 0d
3 0e
4 0f
4 11
6 12
1 14
7 15
3 16
7 17
4 18
1 19
6 1a
3 1b
3 1c
3 1d
11 1e
3 1f
6 20
4 21
2 22
3 23
8 24
3 25
2 26
7 27
3 28
7 29
4 2a
4 2b
9 2c
2 2d
5 2e
2 2f
5 30
7 31
6 32
3 33
6 34
8 35
5 36
2 37
2 38
5 39
2 3a
1 3b
4 3c
3 3d
2 3e
2 3f
2 40
3 41
5 42
5 43
3 44
4 45
5 46
4 47
5 48
5 49
5 4a
5 4b
8 4c
6 4d
3 4e
5 4f
4 50
2 51
4 52
2 53
2 54
3 55
7 56
2 57
5 58
3 59
3 5a
5 5b
2 5d
1 5e
9 5f
3 60
3 61
3 62
6 63
3 64
1 65
7 66
4 67
3 68
4 69
4 6a
3 6b
6 6c
4 6d
3 6e
3 6f
7 70
4 71
2 72
5 73
2 74
1 75
5 76
3 77
10 78
2 79
7 7a
5 7b
6 7c
6 7d
5 7e
5 7f
El byte más alto es 0x7f. Y ese es el byte final que todavía tiene un 0
como el bit más significativo. (No publicaré todos los miles de ellos aquí, pero todas las claves privadas que tenían 0x00 como su primer byte tenían su segundo byte > = 0x80. (No había ninguna clave privada que comenzara con 0x0000). Y todas las claves privadas NO tenían 0x00 como su primer byte luego tuvo su segundo byte < = 0x7f.)