error de autenticación OpenSSL dgst

1

He intentado reproducir el flujo de trabajo presentado en este blog en OpenSSL: enlace

Sin embargo, la autenticación parece fallar a pesar de muchas variaciones. ¿Qué está mal? Por favor, vea el código a continuación que puede copiar y pegar en OpenSSL. Tenga en cuenta que estoy usando la versión compacta de OpenSSL para Windows.

//================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

¿Alguna idea de por qué se produce el error de verificación?

    
pregunta Mike 18.07.2013 - 14:54
fuente

2 respuestas

2

El motivo inmediato del error de verificación es que la firma se generó en friendencryptedpasswordbase64.txt , pero intenta verificarla en phase2friendencryptedpassword.txt , que no tiene el mismo contenido. Las firmas se calculan sobre secuencias de bytes y no le importa si visualiza estos bytes como la codificación Base64 de algunos otros bytes. Si desea que la firma sea verificable, debe usar la misma secuencia de bytes que el mensaje firmado para la generación y la verificación.

En general, lo que estás tratando de hacer no está claro; en particular, lo que usted llama "Cifrar la contraseña de un amigo usando la clave privada de un amigo" no lo hace no . Lo que obtienes con esa línea de comandos no es cifrado; es más bien una media firma (el archivo de entrada, friendpassword.txt , se toma "tal cual" como si fuera un valor hash, incrustado en un "PKCS # 1 v1.5 tipo 1 relleno", y sujeto a la RSA núcleo exponencial modular). En particular, al usar el valor friendencryptedpassword.txt y la clave pública friendpublickey.txt , que son públicas (ya que se envían "en el cable"), es trivial reconstruir friendpassword.txt , y apuesto a que eso no es lo que querría que sucediera.

Si lo que quieres es que el usuario A transmite al usuario B algún valor secreto V (por ejemplo, una "contraseña") para que el intruso no pueda ver V , pero B tiene alguna garantía de que lo que se recibió es un mensaje de A, entonces lo que debería suceder es que:

  • A cifra el valor V con la clave pública de B, con el resultado de W .
  • A firma W con la clave privada de A, obteniendo una firma S .
  • A envía W y S a B.
  • B verifica S sobre la entrada W , usando la clave pública de A. Esto le da a B cierta garantía de que W es de hecho el valor que A envió (no fue alterado en el tránsito por algún interloper malévolo).
  • B descifra W con la clave privada de B, obteniendo V .

Tenga en cuenta que A mantiene su clave privada privada, y que también lo hace B. A nunca aprende la clave privada de B, y B nunca aprende la clave privada de A. Además, el par de claves de B se utiliza para encriptación y el par de claves de A para firmas . El cifrado y la firma son actividades distintas que utilizan algoritmos distintos y distintos tipos de claves. Es una fuente desafortunada de confusión que exista un algoritmo de cifrado llamado RSA, y también un algoritmo de firma llamado RSA, y ambos tipos de RSA pueden compartir la misma estructura de claves; aún más confuso, muchas personas se refieren erróneamente a las firmas como "cifrado con la clave privada", lo cual es incorrecto y hace que la imagen general sea especialmente oscura. Será mejor que mantenga separadas las firmas y el cifrado (y hay buenas razones para eso).

Hay muchos detalles que pueden fallar en cualquier momento en el diseño e implementación de dichos protocolos, por lo que la forma más segura es confiar en protocolos estándar que han sido cuidadosamente especificados y analizados, y en herramientas que implementan estos protocolos y han sido probados a fondo para su corrección. Para ser breve, utilice GnuPG .

    
respondido por el Thomas Pornin 18.07.2013 - 19:33
fuente
0

Última versión corregida:

//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
    
respondido por el Mike 19.07.2013 - 06:02
fuente

Lea otras preguntas en las etiquetas