Non sono sicuro del motivo per cui vuoi tagliare i byte. Quindi non sono sicuro che questa sia una buona risposta alla tua domanda qui va comunque.
Ecco cosa ho scoperto leggendo le RFC / sperimentando.
How can I adjust the size of the private to 32 Bytes and public key to 64 Bytes?
Non devi. Sono già in quella forma. È solo un po 'di confusione leggere dalla stampa di openssl.
Does the leading 00 change the value of the number?
La risposta è "No" se lo si analizzasse comunque come unsigned int. (E "sì" se tu fossi (erroneamente) andando ad analizzarlo come int firmato. In tal caso devi mantenere il prefisso 0x00.)
TLDR : il 0x00 iniziale è un SIGN BY che aggiunge openssl solo per la stampa. NON è codificato nel certificato stesso. E suppongo che tu possa tagliare il byte principale (uno di 0x02, 0x03 o 0x04 ) del pubkey perché memorizza solo informazioni sulla codifica compressa o non compressa.
Chiave di esempio con nullbyte iniziale
Ecco un esempio di una chiave casuale che ho generato:
$ cat leading-nullbyte.pem
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIN/37NFyCvL7brp4zljP83sNj1PvtFsp8dMR86EDwLZUoAoGCCqGSM49
AwEHoUQDQgAEK0acP7Ml6fgKy35YE7JGVP7AmNy7oJ6gl4QIqiwiSExbr4iDPfxT
81550HxXoiQiBJXBJxhgXYpIcJVmFGk20w==
-----END EC PRIVATE KEY-----
ec print leading-nullbyte.pem
Questa chiave è mostrata con il prefisso "00:" per la chiave privata.
Almeno quando usi la stampante graziosa openssl ...
$ 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
... tuttavia, quando guardi realmente dentro la codifica ASN1 non c'è nessun prefisso 00:
. Inizia subito con df:
. E anche: la lunghezza è data come 32 ( l= 32
). Non 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..{
Ecco le righe nel loro contesto:
$ 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.
Quindi il 0x00 iniziale non è effettivamente codificato nel file del certificato. Mentre non ho dato un'occhiata al codice sorgente di openssl per quanto riguarda il fatto che sono propenso a chiamare questo bug di stampa.
Secondo RFC5915 (penso) una chiave EC è un intero UNSIGNED.
Chiave di esempio SENZA nullbyte iniziale
Ecco un'altra chiave casuale che ho generato. NON ha il prefisso 0x00 quando si usa la stampante openssl ec pretty.
Quindi questo mi dice che quel prefisso 0x00 non è necessariamente lì per ogni privkey EC.
$ cat no-leading-nullbyte.pem
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIAGcFoPfqfFZ5TDv71ZBBCctapiVKwZikE8HfKf61V1DoAoGCCqGSM49
AwEHoUQDQgAENPjKv9vobJnz1FSlSu5cNPyPwCvcsMmIr5HH92C+mZdVtanHwlTm
29IwOE5lSE8KMywIJs8pLCvX79kJhZ/upg==
-----END EC PRIVATE KEY-----
ec stampa 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
asn1punto no-leading-nullbyte.pem
Qui di nuovo la lunghezza è data come 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.'
Analisi completa:
$ 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: come faccio a sapere che 0x00 è un byte di segno?
... per sperimentazione:
Ho generato migliaia di chiavi in questo modo:
$ for i in $(seq -w 1000); do echo $i; openssl ecparam -name prime256v1 -genkey -noout > key.$i.pem; done
E poi li ho ordinati e contati per primo byte in questo modo:
$ 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
Il byte più alto è 0x7f. E questo è il byte finale che ha ancora un 0
come il bit più significativo. (Non posterò tutti i migliaia di questi qui, ma tutti i privkey che avevano 0x00 come primo byte avevano il loro secondo byte > = 0x80. (Non c'erano i privati che iniziarono con 0x0000.) E tutti i privkey non avevano 0x00 come il loro primo byte aveva il loro secondo byte < = 0x7f.)