¿Por qué PGP usa cifrado simétrico y RSA?

21

Al analizar los detalles de Pretty Good Privacy, estoy confundido en cuanto al razonamiento detrás del cifrado del mensaje con una clave de sesión y la clave con la clave pública del destinatario a través de RSA. No veo cómo esto es más seguro que el simple cifrado RSA del mensaje real.

Es muy probable que sea demasiado ingenuo en términos de seguridad y cifrado, pero si puedo obtener su clave privada RSA, ¿por qué importa si eso me da acceso al cuerpo del mensaje o la otra clave que lo hará? desbloquear el cuerpo del mensaje?

    
pregunta Ken Bellows 17.06.2013 - 03:55
fuente

4 respuestas

32

RSA no está realmente diseñado para cifrar grandes fragmentos de texto sin formato. Cada "ronda" de RSA puede cifrar 117 bytes de datos, y para cifrar más, tendría que usar un modo de encadenamiento . Actualmente, esto significa una sobrecarga adicional, lentitud (recuerde, RSA es bastante lento) y la incertidumbre de seguridad (RSA-chaningMode no se ha analizado como otros tipos de esquemas de cifrado). < - BAD

Al utilizar cifrado híbrido (simétrico + asimétrico para la clave simétrica) obtiene el beneficio de la asimetría, es decir, no tener que preocuparse por intercambiar llaves; Y simétrico, muy rápido y ha sido bien examinado. < - BUENO

Para obtener más información, consulte: ¿Cómo puedo usar el cifrado asimétrico, como RSA, para cifrar una longitud arbitraria de texto plano?

    
respondido por el Adi 17.06.2013 - 04:24
fuente
10

RSA es un algoritmo lento, especialmente para descifrado. Tienes que calcular m = c^d mod N donde d es aproximadamente el tamaño del módulo. Para RSA-1024/2048/4096 (donde 1024/2048/4096 es el número de bytes del módulo N), incluso con una rápida exponencia modular al cuadrar repetidamente, requiere aproximadamente 1.5 lg N (~ 1500 / ~ 3000 / ~ 6000) Multiplicación de enteros de N bits. La multiplicación de un entero de N bits no es una operación primitiva, pero se escala como O (N ^ 1.6) para un entero de n bits (por lo tanto, cada multiplicación es aproximadamente 84/256/776 veces más lenta que una primitiva de multiplicación de 64 bits).

Nota: el cifrado RSA es significativamente más rápido que el descifrado, ya que con el relleno adecuado no hay ninguna debilidad en elegir un exponente de clave pública pequeño como e = 65537, donde su paso de exponenciación solo requiere ~ 17 multiplicaciones; de hecho, e = 3 que requiere solo dos multiplicaciones funcionaría perfectamente bien con el relleno adecuado.

Además, una aplicación de RSA de b bits significa que tuvo que generar dos números primos de aproximadamente cada una de esa longitud) solo puede descifrar un mensaje de hasta aproximadamente B-128 bits (utilizando un relleno aleatorio de 128 bits) o aproximadamente 112 / 240/496 bytes ya que solo descodifica un número entre 0 y N. Esta respuesta con codificación ASCII de 8 bits necesitaría 7449 bytes.

Por lo tanto, lo que sucede habitualmente es que simplemente cifras una clave simétrica, ya que la clave simétrica será mucho más rápida y el uso de un modo de cifrado (por ejemplo, CBC, CTR) puede cifrar mensajes de tamaño arbitrario.

Información de tiempo para justificar el análisis anterior

Creé aleatoriamente un par de claves RSA de 4096 bits (N, e) y (N, d) (usando import rsa; rsa.newkeys(nbits=4096) ) y luego hice cronogramas para comparar "libro de texto" (débil, sin bytes rellenados) cifrado / descifrado RSA al cifrado AES.

La configuración para la temporización de RSA se da a continuación del cifrado / descifrado:

>>> encryption = "pow(m,e,N)"
>>> decryption = "pow(c,d,N)"
>>> setup =  """N = 650022002033202164791638561174816123258916492020045683486079596172818033518252144860009135975860423604411399274822133841546708494765449009472683563317182198759309684914356008659922538583279515419473227210977474088638850782595732910857797571156318425669817244314450827318145758475770172116229990603884173470104902799641093008914867436680133631971559712828465243806241512864086546090728020169682901285441149037545107765998640217114788723715575098893307499744794060936075307573516246976128444578474543743151813381476261995022381469996299316134038828450334308951123635607639233510908350391842701316709834010335732144351192249236953330927673972067894385163240378028762678952835544528074929660347162229394149982403274141710996800529609644247153732931740566379474447028470447165473543764460712691302632667942726305345440613110797535733482536487121364569032950159436896042439632454394173272272373593467791776848612054118558722637286863035388661691125609333937871344046274188817824229897604542696165894703693345718292207375417809743565484488696015562272970275127353631067240331072960179800283770558952793368549384848991363395614092594834723746484679602433778811932755737361396956451757817273043140309312219744371338360280947729616063853738641

e = 65537

d = 163256819101675505935126275492278764497028632049833711493978518287449606050176698725845711249563797130302144316394896364372168726426893063398086141449880510117616574052677112204439095245140620165777031598832556014144612720776443287192263118867708337069520909431555619232749121633751575949969416441703671137188560661642925231956585104715733090960096935672315454064890600755952584778878850298197667808388563912873529057301030226798746088352508752731797937742028323588321094384242144517250929974849184277771012531228150089843422784017258750683831715157735366668225506845014904307329056055723208632277201486994123654288753880392020556964543443597828229493325467616467308118864809565200248599428162198788308364968380312577988297310500286974136209331121821893719017982045957945241683426015912952303440579610553088057331105677592306795472995839704525934407019706992740653789223747419222232691256397983243926154436341276701812083801394467756814989897357722664273229362826815661611670740504736110949984419908621950792127278167263015929591331285519955311164883226113070661776218890597216617564529563317568347817244502395174702566462626236588608296425638109493962233171124725237010153412040065506840529586822535766472003407847003802265141256193

m= int("This is a secret message provided as a test for RSA-4096 and AES encryption.  To be fair it is 496 bytes long.  Keyboard mashing follows: asdbklajsdgl;sdjgl;kasjdgiowepgj opijg aslekgjase;lgk jasel; elask;gj lask;lgjl;ske gjasle;k asel;k gjl;asekgj asljsel;k jseal; gkjasel; kjsael;kjg aal;se asegkl;j asel;kjasegl;k jasegl;k jasel;gk jasegl;k jasel gkjsael;gkjasel;gkj sea;lekgjseal;kjasegl;asekgjasel;kgjsael;jkasel;gjkgasel;asfasfl;kjasf;lkjsadfkljdl;kfaskl;jfasldk;fkfkjl;akasdfasdfasdfkjkjga".encode('hex'),16)
c = pow(m, e, N)
"""
>>> import timeit
>>> timeit.repeat(encryption, setup=setup, repeat=3, number=1)
[0.0044488906860351562, 0.0045480728149414062, 0.0044538974761962891]

>>> timeit.timeit(decryption, setup=setup, repeat=3, number=1)  
[1.9231810569763184, 1.9048171043395996, 1.9280149936676025]

El cifrado RSA de 4096 bits toma ~ 4.5ms por ejecución y el descifrado toma 1.9 segundos (~ 500 veces más lento que el cifrado ya que d es mucho más grande que e). Cifrar este mensaje con RSA requeriría 16 bloques y tardaría unos 30 segundos en descifrarlo. Repitiendo para otros tamaños de RSA, encontré que el RSA de 1024 bits toma ~ 0.5 ms para el cifrado y 40ms para el descifrado. El RSA de 2048 bits toma ~ 1.6ms para el cifrado y ~ 270 ms para el descifrado.

Ahora echemos un vistazo a AES-128, utilizando la biblioteca de pycrypto.

setup = """
from Crypto.Cipher import AES 
from Crypto import Random
from hashlib import sha256

def aes_encrypt(plaintext, key):
    block_size = AES.block_size
    iv = Random.new().read(block_size)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    pad_len = block_size - (len(plaintext) % block_size)
    padding = ''.join([chr(pad_len)]*pad_len)
    encrypted_msg = iv + cipher.encrypt(plaintext + padding)
    return encrypted_msg

def aes_decrypt(encrypted_msg, key):
    block_size = AES.block_size
    iv = encrypted_msg[:block_size]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_msg = cipher.decrypt(encrypted_msg[block_size:])
    pad_len = ord(padded_msg[-1])
    msg = padded_msg[:len(padded_msg)-pad_len]
    return msg

key = sha256("secret passphrase").digest()[0:16]
message = "This is a secret message provided as a test for RSA-4096 and AES encryption.  To be fair it is 496 bytes long.  Keyboard mashing follows: asdbklajsdgl;sdjgl;kasjdgiowepgj opijg aslekgjase;lgk jasel; elask;gj lask;lgjl;ske gjasle;k asel;k gjl;asekgj asljsel;k jseal; gkjasel; kjsael;kjg aal;se asegkl;j asel;kjasegl;k jasegl;k jasel;gk jasegl;k jasel gkjsael;gkjasel;gkj sea;lekgjseal;kjasegl;asekgjasel;kgjsael;jkasel;gjkgasel;asfasfl;kjasf;lkjsadfkljdl;kfaskl;jfasldk;fkfkjl;akasdfasdfasdfkjkjga"
cipher = aes_encrypt(message,key)
"""

>>> timeit.repeat("aes_encrypt(message,key)", setup=setup, repeat=3, number=1)
[6.198883056640625e-05, 6.198883056640625e-05, 6.008148193359375e-05]

>>> timeit.repeat("aes_decrypt(cipher,key)", setup=setup, repeat=3, number=1)
[1.0967254638671875e-05, 9.059906005859375e-06, 9.059906005859375e-06]

Línea inferior , el cifrado AES es aproximadamente 25/08/5 más rápido que el RSA y el descifrado AES es aproximadamente 4000/25000/200000 veces más rápido que RSA (a 1024/2048/4096 bit encriptación respectivamente). Por lo tanto, el cifrado híbrido siempre tiene sentido siempre que necesite más de un bloque.

    
respondido por el dr jimbob 17.06.2013 - 04:45
fuente
2

De algo que escribí hace 3 años: "Hay 2 tipos básicos de cifrado que utilizamos todos los días de nuestras vidas. Todos los utilizan. Incluso mi abuela.

El Tipo 1 es Simétrico, también conocido como Clave única, también conocido como Clave secreta, también conocido como súper rápido ... Observe cómo todas las palabras S van juntas :)

El Tipo 2 es Asymmetric, también conocido como Clave Pública / Clave Privada (o simplemente clave pública para abreviar), también conocido como Two Key, también conocido como encriptación realmente lenta y lenta. Esto es lo que la gente generalmente piensa que están usando cuando usan PGP. (lo están, pero también están utilizando el cifrado simétrico para realizar la mayor parte del trabajo) " enlace

Básicamente, como lo demostró anteriormente el Dr. jimbob, la clave pública es demasiado lenta para el cifrado masivo. Mezclando eso con arreglos simétricos, y la razón por la que no usamos simétricamente solo es que hay un problema de intercambio de claves. ¿De qué otra manera nos aseguramos de que nuestro destinatario deseado reciba la clave y ellos sean los únicos que obtengan la clave?

    
respondido por el Rod MacPherson 18.06.2013 - 01:29
fuente
1

Otra razón por la que esto es útil es porque aumenta la flexibilidad. Por ejemplo, cifrar solo la clave de sesión le permite usar varios pares de claves con una sobrecarga relativamente baja. Solo agrega una clave de sesión encriptada por par de llaves.

    
respondido por el Tim Lamballais 17.06.2013 - 10:10
fuente

Lea otras preguntas en las etiquetas