Errore di autenticazione dgst di OpenSSL

1

Ho provato a replicare il flusso di lavoro presentato su questo blog in OpenSSL: link

Tuttavia, l'autenticazione sembra fallire nonostante molte varianti. Cosa c'è che non va? Si prega di consultare il codice qui sotto è possibile copiare e incollare in OpenSSL. Nota che sto usando la versione binaria di Windows di OpenSSL compilata.

//================Phase 1 - Setup================

//Generate my private key (myprivatekey.txt)
genpkey -algorithm RSA -out C:\myprivatekey.txt -pass pass:abc123 -pkeyopt rsa_keygen_bits:2048

//Generate friend's private key (friendprivatekey.txt)
genpkey -algorithm RSA -out C:\friendprivatekey.txt -pass pass:123abc -pkeyopt rsa_keygen_bits:2048

----------------

//Extract my public key (mypublickey.txt) from my private key (myprivatekey.txt)
rsa -passin pass:abc123 -in C:\myprivatekey.txt -pubout -out C:\mypublickey.txt

//Extract friend's public key (friendpublickey.txt) from my private key (friendprivatekey.txt)
rsa -passin pass:123abc -in C:\friendprivatekey.txt -pubout -out C:\friendpublickey.txt

----------------

//Generate my password (a random base64 string password saved mypassword.txt)
rand -base64 -out C:\mypassword.txt 128

//Generate friend's password (a random base64 string password saved to friendpassword.txt)
rand -base64 -out C:\friendpassword.txt 128

//Delete the .rnd file that's generated?  Not sure what it is.

----------------

//Encrypt my password using my private key (encrypted password saved to a binary file - myencryptedpassword.txt)
pkeyutl -in C:\mypassword.txt -out C:\myencryptedpassword.txt -inkey C:\myprivatekey.txt -passin pass:abc123

//Encrypt friend's password using friend's private key (encrypted password saved to a binary file - friendencryptedpassword.txt)
pkeyutl -in C:\friendpassword.txt -out C:\friendencryptedpassword.txt -inkey C:\friendprivatekey.txt -passin pass:123abc

----------------

//Convert my encrypted password to base64 from binary (saved as myencryptedpasswordbase64.txt)
base64 -in C:\myencryptedpassword.txt -out C:\myencryptedpasswordbase64.txt

//Convert friend's encrypted password to base64 from binary (saved as friendencryptedpasswordbase64.txt)
base64 -in C:\friendencryptedpassword.txt -out C:\friendencryptedpasswordbase64.txt

----------------

//Create a signed hash of my password so my friend knows it's coming from me (signed hash saved as mysignedhash.txt and is in binary form)
dgst -sha256 -sign C:\myprivatekey.txt -passin pass:abc123 -out C:\mysignedhash.txt C:\myencryptedpasswordbase64.txt

//Create a signed hash of friend's password so I know it's coming from my friend (signed hash saved as friendsignedhash.txt and is in binary form)
dgst -sha256 -sign C:\friendprivatekey.txt -passin pass:123abc -out C:\friendsignedhash.txt C:\friendencryptedpasswordbase64.txt

----------------

//Convert my signed hash from binary to base64
base64 -in C:\mysignedhash.txt -out C:\mysignedhashbase64.txt

//Convert friend's signed hash from binary to base64
base64 -in C:\friendsignedhash.txt -out C:\friendsignedhashbase64.txt

//================Phase 2 - Authentication================

//Now, we reverse the process and authenticate the friend.  Let's prefix all output files with "phase2"

//I provide friend with my public key and my encrypted password 
//Friend provides me with their public key

//Convert friend's encrypted password from base64 to binary.  The output file will be the same as friendsignedhash.txt
base64 -d -in C:\friendsignedhashbase64.txt -out C:\phase2friendsignedhash.txt

//Convert friend's signed hash from base64 to binary.  The output file will be the same as C:\friendsignedhash.txt
base64 -d -in C:\friendencryptedpasswordbase64.txt -out C:\phase2friendencryptedpassword.txt

//Verify if the password originates from my friend (by checking against my friend's public key)
dgst -sha256 -verify C:\friendpublickey.txt -signature C:\phase2friendsignedhash.txt -out C:\friendresult.txt C:\phase2friendencryptedpassword.txt

Qualche idea sul perché l'errore di verifica si verifica?

    
posta Mike 18.07.2013 - 14:54
fonte

2 risposte

2

Il motivo immediato della mancata verifica è che la firma è stata generata su friendencryptedpasswordbase64.txt , ma provi a verificarla su phase2friendencryptedpassword.txt , che non ha lo stesso contenuto. Le firme vengono calcolate su sequenze di byte e non interessa se si prevedono questi byte come codifica Base64 di alcuni altri byte. Se si desidera che la firma sia verificabile, è necessario utilizzare la stessa sequenza di byte come messaggio firmato sia per la generazione che per la verifica.

Nel complesso, ciò che stai cercando di fare non è chiaro; in particolare, ciò che chiami "Cripta la password dell'amico utilizzando la chiave privata dell'amico" fa non . Quello che ottieni con quella riga di comando non è crittografia; è piuttosto una mezza firma (il file di input, friendpassword.txt , è preso "così com'è" come se fosse un valore hash, incorporato in un "padding di tipo 1 di PKCS # 1 v1.5", e soggetto alla RSA core modular exponentiation). In particolare, usando il valore friendencryptedpassword.txt e la chiave pubblica friendpublickey.txt , entrambi pubblici (dato che vengono inviati "sul filo"), è banale ricostruire friendpassword.txt , e scommetto che non è quello che vorrebbe succedere.

Se quello che vuoi è che l'utente A trasmetta all'utente B qualche valore segreto V (es. una "password") in modo che l'intercettatore non possa vedere V , ma B ha una certa garanzia che ciò che è stato ricevuto è effettivamente un messaggio da A, quindi ciò che dovrebbe accadere è che:

  • A crittografa il valore V con la chiave pubblica di B, restituendo W .
  • Un segno W con la chiave privata di A, che produce una firma S .
  • A invia W e S a B.
  • B verifica S sopra l'input W , usando la chiave pubblica di A. Ciò garantisce a B che W è effettivamente il valore inviato da A (non è stato alterato in transito da qualche intruso malevolo).
  • B decodifica W con la chiave privata di B, restituendo V .

Si noti che A mantiene privata la sua chiave privata, così come B. A non impara mai la chiave privata di B, e B non impara mai la chiave privata di A. Inoltre, la coppia di chiavi di B è usata per encryption e la coppia di chiavi di A per firme . La crittografia e la firma sono attività distinte che utilizzano algoritmi distinti e tipi distinti di chiavi. È una sfortunata fonte di confusione che esiste un algoritmo di crittografia chiamato RSA e anche un algoritmo di firma chiamato RSA, ed entrambi i tipi di RSA possono condividere la stessa struttura chiave; ancora più confusamente, molte persone si riferiscono erroneamente alle firme come "crittografare con la chiave privata", il che è sbagliato e rende il quadro generale particolarmente oscuro. Faresti meglio a tenere separate le firme e la crittografia (e ci sono buone ragioni per quello).

Ci sono dettagli di gazillion che possono andare storto in qualsiasi momento nella progettazione e nell'implementazione di tali protocolli, quindi il modo sicuro è affidarsi a protocolli standard che sono stati accuratamente specificati e analizzati e agli strumenti che implementano questi protocolli e sono stati accuratamente testati per la correttezza. Per essere brevi, utilizza GnuPG .

    
risposta data 18.07.2013 - 19:33
fonte
0

Ultima versione corretta:

//A is me
//B is friend
//V is my password
//W is my encrypted password
//S is my encrypted password's signature
//The purpose of using base64 encoding is for regular text-based transmission

----------------Phase I - Creating Keys, Password and Signature----------------

//Generate my private key (myprivatekey.txt)
genpkey -algorithm RSA -out C:\myprivatekey.txt -pass pass:abc123 -pkeyopt rsa_keygen_bits:2048

//Generate friend's private key (friendprivatekey.txt)
genpkey -algorithm RSA -out C:\friendprivatekey.txt -pass pass:123abc -pkeyopt rsa_keygen_bits:2048

----------------

//Extract my public key (mypublickey.txt) from my private key (myprivatekey.txt)
rsa -passin pass:abc123 -in C:\myprivatekey.txt -pubout -out C:\mypublickey.txt

//Extract friend's public key (friendpublickey.txt) from my private key (friendprivatekey.txt)
rsa -passin pass:123abc -in C:\friendprivatekey.txt -pubout -out C:\friendpublickey.txt

----------------

//Generate my password (a random base64 string password saved mypassword.txt)
rand -base64 -out C:\mypassword.txt 128

//Generate friend's password (a random base64 string password saved to friendpassword.txt)
rand -base64 -out C:\friendpassword.txt 128

----------------

//Encrypt my password with my friend's public key for later use (A encrypts the value V with B's public key, yielding W.)
rsautl -encrypt -pubin -inkey C:\friendpublickey.txt -in C:\mypassword.txt -out C:\myencryptedpassword.txt

//Encrypt friend's password with my public key for later use
rsautl -encrypt -pubin -inkey C:\mypublickey.txt -in C:\friendpassword.txt -out C:\friendencryptedpassword.txt

----------------

//Create a signed hash of my password so my friend knows it's coming from me (signed hash saved as mysignedhash.txt and is in binary form) (A signs W with A's private key, yielding a signature S.)
dgst -sha256 -sign C:\myprivatekey.txt -passin pass:abc123 -out C:\mysignedencryptedpassword.txt C:\myencryptedpassword.txt

//Create a signed hash of friend's password so I know it's coming from my friend (signed hash saved as friendsignedhash.txt and is in binary form)
dgst -sha256 -sign C:\friendprivatekey.txt -passin pass:123abc -out C:\friendsignedencryptedpassword.txt C:\friendencryptedpassword.txt

----------------

//Create base64 versions of my password and my signature for easy transmission
//Password
base64 -in C:\myencryptedpassword.txt -out C:\myencryptedpasswordbase64.txt
//Signature
base64 -in C:\mysignedencryptedpassword.txt -out C:\mysignedencryptedpasswordbase64.txt

//Create base64 versions of friend's password and friend's signature for easy transmission
//Password
base64 -in C:\friendencryptedpassword.txt -out C:\friendencryptedpasswordbase64.txt
//Signature
base64 -in C:\friendsignedencryptedpassword.txt -out C:\friendsignedencryptedpasswordbase64.txt

----------------Phase II - Verifying Signature and Decrypting Password----------------

//For testing purposes, let's now say that I sent my password and signature to my friend.  My friend now wants to verify the password is from me.

//Convert my password and signature from base64 to binary
//Password
base64 -d -in C:\myencryptedpasswordbase64.txt -out C:\phase2myencryptedpassword.txt
//Signature
base64 -d -in C:\mysignedencryptedpasswordbase64.txt -out C:\phase2mysignedencryptedpassword.txt

//Verify the signature using my public key (B verifies S over input W, using A's public key. This gives B some guarantee that W is indeed the value that A sent (it was not altered in transit by some malevolent interloper))
dgst -sha256 -verify C:\mypublickey.txt -signature C:\phase2mysignedencryptedpassword.txt -out C:\phase2verificationresult.txt C:\phase2myencryptedpassword.txt
//Yay - this produces "Verified OK"

//Decrypt my password (B decrypts W with B's private key, yielding V.)
rsautl -decrypt -inkey C:\friendprivatekey.txt -in C:\phase2myencryptedpassword.txt -out C:\phase2mydecryptedpassword.txt
//Yay - this produces my password for my friend to see
    
risposta data 19.07.2013 - 06:02
fonte

Leggi altre domande sui tag