Solo tengo conocimientos teóricos muy básicos sobre RSA.intercambio de clave pública/privada en PKCS n. ° 1 OAEP cifrado/descifrado
Al leer diferentes fuentes sobre cómo usarlo en la práctica, parecía que PKCS # 1 OAEP sería una buena cosa.
Para una implementación de prueba, utilizo Python con PyCrypto. P.ej. this es un ejemplo que usa PKCS # 1 OAEP.
Encriptar usando la clave pública y luego descifrar usando la clave privada funciona bien. P.ej. el público puede enviar algunos datos a la persona X con la clave privada.
Desde mi comprensión básica de cómo funciona RSA, pensé que solo puedo intercambiar la clave pública/privada, es decir, puedo usar la clave pública para encriptar y la clave privada para descifrar. P.ej. la persona X puede encriptar algunos datos con su propia clave privada y el público puede descifrarlos usando la clave pública. Si el descifrado funciona bien, esto proporciona algún tipo de prueba de que los datos provienen de la persona X.
PyCrypto se queja cuando trato de descifrar usando la clave pública.
De la lectura del código fuente PyCrypto, en la función _RSAKey._decrypt
(here), parece que el propio objeto clave sabe si se trata de la clave privada o pública y la diferencia entre ellos (para mi sorpresa, de nuevo basado en mi muy básico Comprensión de RSA).
A partir de ahí, parece que podría hackear la función de descifrado para que use la clave pública. O algo diferente: podría simplemente intercambiar el exponente público e
y el exponente privado d
en los objetos clave.
Pero todo esto parece que no está destinado a ser utilizado/pirateado de esta manera. Así que quería preguntar aquí sobre mis malentendidos.
Además, sólo por curiosidad, me genera algunas teclas (RSA.generate(2048)
) y se veía en n
, e
y d
. En todos los casos, n
y d
fue muy grande, mientras que e
fue en todos los casos constante (65537) (no me esperaba).
Supongo que de todo esto que realmente no debería simplemente intercambiar e
y d
.
Así que supongo que debería usar algún otro método para la firma como PKCS1_PSS.
algo de código para el cifrado/descifrado, si alguien está interesado: (. binstruct
es un pequeño módulo que puede codificar/estructuras de datos de árboles decodificar - similar a JSON/BSON)
def randomString(l):
import random
return ''.join(chr(random.randint(0, 0xFF)) for i in range(l))
def genkeypair():
from Crypto.PublicKey import RSA
key = RSA.generate(2048)
pubkey = key.publickey().exportKey("DER")
privkey = key.exportKey("DER")
return (pubkey,privkey)
def encrypt(v, rsapubkey):
from Crypto.PublicKey import RSA
rsakey = RSA.importKey(rsapubkey)
from Crypto.Cipher import PKCS1_OAEP
rsa = PKCS1_OAEP.new(rsakey)
import binstruct
from array import array
aeskey = randomString(32)
iv = randomString(16)
from Crypto.Cipher import AES
aes = AES.new(aeskey, AES.MODE_CBC, iv)
data = binstruct.varEncode(v)
data += array("B", (0,) * (-len(data) % 16))
out = binstruct.strEncode(rsa.encrypt(aeskey + iv))
out += array("B", aes.encrypt(data))
return out
def decrypt(stream, rsaprivkey):
from array import array
from StringIO import StringIO
if isinstance(stream, array): stream = stream.tostring()
if isinstance(stream, str): stream = StringIO(stream)
from Crypto.PublicKey import RSA
rsakey = RSA.importKey(rsaprivkey)
from Crypto.Cipher import PKCS1_OAEP
rsa = PKCS1_OAEP.new(rsakey)
import binstruct
aesdata = binstruct.strDecode(stream)
aesdata = rsa.decrypt(aesdata)
aeskey = aesdata[0:32]
iv = aesdata[32:]
from Crypto.Cipher import AES
aes = AES.new(aeskey, AES.MODE_CBC, iv)
class Stream:
buffer = []
def read1(self):
if len(self.buffer) == 0:
nextIn = stream.read(16)
self.buffer += list(aes.decrypt(nextIn))
return self.buffer.pop(0)
def read(self, n):
return "".join([self.read1() for i in range(n)])
v = binstruct.varDecode(Stream())
return v
Ahí es donde pensé que también podría usar encrypt
con la clave privada yy decrypt
con la clave pública.
La aplicación final con (esperemos) correcta firma/autenticación se puede encontrar here in binstruct.
"PyCrypto se queja cuando trato de descifrar usando la clave pública". Por favor, sea más específico y muestre su código. –
@GregS: Se levanta 'TypeError (" Sin clave privada ")' en '_RSAKey._decrypt'. Como puede ver en el código vinculado. Eso es lo que dije. Parece que necesita la clave privada para descifrar. – Albert
Si solo tiene un conocimiento rudimentario de la criptografía, no sirve usar la API de forma que no se suponga que deba usarse. Tengo 10 años de experiencia e incluso soy bastante cuidadoso cuando uso bibliotecas criptográficas de una manera que se supone que no debo hacerlo, e intento evitar hacerlo siempre que sea posible. –