L'output OpenSSL Base64 ha una lunghezza errata

0

Cerco di generare una coppia di chiavi ECDH P-256 come richiesto per i messaggi push web.

openssl ecparam -name prime256v1 -genkey -noout -out priv_key.pem

... genera le chiavi.

openssl ec -noout -text -in priv_key.pem

... sembra buono: come previsto, la chiave privata ha 33 byte, la chiave pubblica 65. Quando esporto la chiave pubblica:

openssl ec -in priv_key.pem -pubout -out pub_key.pem

... Mi aspetto che l'output di base64 sia lungo 88 caratteri, ma quello che ottengo è 126. Il server non accetta questa chiave. Ho letto su base64 compressa ( link ), ma questo non risolve il problema (ne risulta un 80 byte stringa base64). Ad ogni modo non riesco a capire come OpenSSL generi questo output di base64.

    
posta wortwart 22.03.2018 - 11:44
fonte

2 risposte

1

Quindi hai ragione riguardo alle lunghezze. Come ha sottolineato Steffen Ullrich, hai un modo per visualizzare la struttura dell'oggetto asn1 utilizzando openssl asn1parse .

Se vuoi estrarre la chiave pubblica e solo la chiave pubblica, devi estrarla dall'oggetto asn1 .

Per farlo:

openssl ec -in priv_key.pem -pubout -outform DER 2> /dev/null | \
dd bs=1 skip=$((2+2+19+2+1)) 2> /dev/null > raw_pub.key

È possibile verificare che la chiave sia lunga 65 byte. Una volta base64 è 88 come hai detto.

Il significato di $((2+2+19+2)) sono i byte che devi saltare per raggiungere l'oggetto BIT STRING che produce la chiave pubblica. Abbiamo anche un ulteriore 1 byte da saltare perché la chiave pubblica ha il seguente formato:

  • 0x00 per padding
  • 0x02 o 0x04 compresso / non compresso
  • il payload della chiave pubblica effettiva

hl è l'acronimo di header length Credo e dove è archiviato il tipo di oggetto, in modo tale da spiegare tutto 2 s.

l sta per length ed è la lunghezza dell'intero oggetto.

d è l'acronimo di depth e indica gli oggetti nidificati, ad esempio, come ad esempio in json .

Quindi BIT STRING è a depth=1 dopo 2:d=1 hl=2 l= 19 cons: SEQUENCE . Dobbiamo aggiungere 19 byte al nostro salto per raggiungere l'intestazione BIT STRING che saltiamo - un altro 2 bytes quindi siamo a destinazione.

EDIT:

Come per i commenti che ho aggiunto e 1 byte in più a causa del padding.

Fonte: rfc5480 # section-2.2

    
risposta data 22.03.2018 - 15:16
fonte
2

Non ottieni i bit grezzi della sola chiave quando lo esporti utilizzando openssl ec -pubout ma una struttura con più informazioni:

$ openssl asn1parse -in pub_key.pem -dump
    0:d=0  hl=2 l=  89 cons: SEQUENCE          
    2:d=1  hl=2 l=  19 cons: SEQUENCE          
    4:d=2  hl=2 l=   7 prim: OBJECT            :id-ecPublicKey
   13:d=2  hl=2 l=   8 prim: OBJECT            :prime256v1
   23:d=1  hl=2 l=  66 prim: BIT STRING        
      0000 - 00 04 11 5e 44 51 b0 95-4e 9b 14 42 e7 60 21 10   ...^DQ..N..B.'!.
      0010 - f0 05 5d b4 bb 76 22 6d-2e 45 66 ad 3a 89 eb f2   ..]..v"m.Ef.:...
      0020 - 15 00 57 89 29 98 ce 84-5e b2 58 83 fb 8d 7a 59   ..W.)...^.X...zY
      0030 - 6d 11 2e 5d c3 7c e1 df-4a c9 ce a6 94 89 61 2a   m..].|..J.....a*
      0040 - dc 06

Quindi, ottieni essenzialmente 91 ottetti binari che si traducono in 124 caratteri quando codificati come base64.

    
risposta data 22.03.2018 - 14:25
fonte

Leggi altre domande sui tag