Vil du forstå Pretty Good Privacy? Simuler det.

Som navnet antyder, er Pretty Good Privacy (eller PGP) et krypteringsprogram, der faktisk giver ret godt privatliv. Den "temmelig gode" bit er beregnet til at være lidt af en ironisk underdrivelse. Det har været en af ​​de dominerende former for end-to-end-kryptering til e-mail-kommunikation efter dets udvikling af Phil Zimmermann i 1991. Det blev stadig mere populært efter dets brug af whistleblower Edward Snowden.

PGP giver to ting, der er vigtige for en sikret kommunikation:

  1. Fortrolighed: Leveres ved brug af symmetrisk blokkryptering, komprimering ved hjælp af ZIP-algoritmen og E-mail-kompatibilitet ved hjælp af radix64-kodningsskemaet
  2. Godkendelse: Leveres ved brug af digitale signaturer

Uden yderligere ado, lad os komme til PGP's funktion.

Hvordan det virker

Jeg vil forklare begrebet PGP set fra implementeringens synspunkt i forbindelse med Alice (afsenderen) og Bob (modtageren). Vi bruger følgende algoritmer:

  1. RSA som den asymmetriske krypteringsalgoritme
  2. SHA-512 som hashingalgoritme
  3. DES som den symmetriske krypteringsalgoritme og
  4. ZIP til komprimering

Du kan også bruge andre algoritmer. (Jeg ved, at DES er for gammel til at blive brugt, men målet her er at forstå begrebet PGP.)

Alice og Bob genererer begge deres par nøgler (offentlige og private nøgler) ved hjælp af RSA-algoritmen. Offentlige nøgler til Alice og Bob skal være kendt af hinanden.

Alice / afsenderens side:

  1. Alice skriver en besked M, som hun har til hensigt at sende til Bob.
  2. M leveres som input til SHA-512-algoritmen for at få den 512 bit binære hash (repræsenteret som 128 bit hexadecimal streng) af den.
  3. Denne hash signeres digitalt ved hjælp af RSA-algoritme, dvs. hasjen krypteres af Alice's private nøgler. Indgangene til RSA er private nøgler til Alice og hash. Outputtet fra RSA er den digitalt signerede hash eller krypterede hash EH.
  4. Nu er M og EH tilføjet sammen. (Tilføjet i den forstand, at de placeres i en række strenge).
  5. M og EH (som er i en række strenge) fungerer som input til ZIP-komprimeringsalgoritmen for at få den komprimerede M og komprimerede EH igen i en række strenge.
  6. Outputtet fra ovenstående trin er nu krypteret ved hjælp af DES symmetrisk krypteringsalgoritme. Til dette genererer vi først SecretKey til DES. Denne nøgle og output fra trin 5 fungerer som input til DES-krypteringsalgoritmen, som giver os et krypteret output (igen i en række strenge).
  7. Sidst men ikke mindst, da M er krypteret ved hjælp af SecretKey, skal den også sendes til Bob. Vi krypterer SecretKey af DES-algoritmen med Bob's Public Key. Vi bruger RSA til dette, og inputene til det vil være den offentlige nøgle for Bob og SecretKey.
  8. Outputene fra trin 6 og 7 tilføjes nu og sendes som den sidste besked til Bob.

Hele meddelelsen sendes som en række strenge ( String finalmessage[]), der indeholder følgende på indekser:

0: Komprimeret besked M, der er krypteret med SecretKey

1: Digital signeret hash EH, som derefter komprimeres og krypteres med SecretKey

2: Output fra trin 7

Bobs / modtagerens side:

  1. Bob vil først dekryptere SecretKey of DES med sine private nøgler. Indgangene til RSA-algoritmen til dette vil være Private Keys of Bob og finalmessage[2]. Output fra RSA vil give Bob SecretKey.
  2. Denne SecretKey fungerer nu som en af ​​input til DES-dekrypteringsalgoritme til dekryptering af finalmessage[0]og finalmessage[1]. Disse to fungerer også som input til DES-dekrypteringsalgoritme. Resultatet af dette trin vil være decrypted versionaf finalmessage[0]og finalmessage[1].
  3. Outputene fra ovenstående trin skal leveres som input til ZIP-algoritmen til dekompression.
  4. Fra output fra ovenstående trin får vi den digitalt underskrevne hash og den originale besked M. Vi kontrollerer, om hasjen blev underskrevet af Alice. Til dette beregner vi hash af den originale besked M ved hjælp af SHA-512 ( calculated_hash). Vi dekrypterer også den digitalt underskrevne hash med Alice's offentlige nøgler ved hjælp af RSA (input til RSA: digitalt signeret hash og offentlige nøgler til Alice og output fra RSA decrypted_hash:).
  5. Sammenlign decrypted_hashog calculated_hash. Hvis de viser sig at være de samme, opnås godkendelse, hvilket betyder, at beskeden faktisk blev sendt af Alice.

Følgende er simuleringen af ​​PGP udført på den enkleste måde ved hjælp af Java.

import java.util.*; import java.math.*; import javax.crypto.Cipher; import java.security.*; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import javax.crypto.spec.*; public class PGP{ static Cipher ecipher, dcipher;//Required for DES public static void main(String args[]) throws Exception{ //Generating sender keys KeyPair senderkeyPair = buildKeyPair(); PublicKey senderpubKey = senderkeyPair.getPublic(); PrivateKey senderprivateKey = senderkeyPair.getPrivate(); //Generating receiver keys KeyPair receiverkeyPair = buildKeyPair(); PublicKey receiverpubKey = receiverkeyPair.getPublic(); PrivateKey receiverprivateKey = receiverkeyPair.getPrivate(); //Sending both public keys and private keys for choice of digital signature or normal assymetric encryption String messagetoreceiver[] = senderside(senderpubKey, senderprivateKey, receiverpubKey, receiverprivateKey); receiverside(messagetoreceiver, senderpubKey, senderprivateKey, receiverpubKey, receiverprivateKey); } public static void receiverside(String messagetoreceiver[], PublicKey senderpubKey, PrivateKey senderprivateKey, PublicKey receiverpubKey, PrivateKey receiverprivateKey) throws Exception { //Receiver receives the message messagetoreceiver[] with messagetoreceiver[2] as secret key encrypted with receiver pub key //Receiver decrypts the messagetoreceiver[2] with his/her privatekey String receiverencodedsecretkey = decrypt(receiverpubKey, receiverprivateKey, messagetoreceiver[2], 1); //Key after decryption is in base64 encoded form byte[] decodedKey = Base64.getDecoder().decode(receiverencodedsecretkey); SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "DES"); System.out.println("\nReceiver Side: Receiver SecretKey DES after Decryption with his/her Private Key=\n"+originalKey.toString()); //Decrypt the rest of the message in messagetoreceiver with SecretKey originalKey String receiverdecryptedmessage[] = new String[messagetoreceiver.length-1]; System.out.println("\nReceiver Side: Message After Decryption with SecretKey="); for (int i=0;i
    
     encryptwithprivatekey 1->encryptwithpublickey public static String encrypt(PublicKey publicKey, PrivateKey privateKey, String message, int ch) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); if (ch == 0) { cipher.init(Cipher.ENCRYPT_MODE, privateKey); byte[] utf8 = cipher.doFinal(message.getBytes("UTF-8")); return new sun.misc.BASE64Encoder().encode(utf8); } else { cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] utf8 = cipher.doFinal(message.getBytes("UTF-8")); return new sun.misc.BASE64Encoder().encode(utf8); } } //n: 0->decryptwithpublickey 1->decryptwithprivatekey public static String decrypt(PublicKey publicKey,PrivateKey privateKey, String st, int ch) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); byte[] encrypted = new sun.misc.BASE64Decoder().decodeBuffer(st); if (ch == 0) { cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] utf8 = cipher.doFinal(encrypted); return new String(utf8, "UTF8"); } else { cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] utf8 = cipher.doFinal(encrypted); return new String(utf8, "UTF8"); } } }
    

Vi har brugt base64-kodningsskemaet, der ligner radix64, der bruges i PGP.

Bemærk:

  1. Vi base64 koder strengene efter kryptering og komprimering for at få en læsbar tekstformular.
  2. Til dekryptering og dekompression sender vi base64-dekodede input som de faktiske input til dekrypterings- og dekompressionsalgoritmerne.
  3. Nøglen er kodet og afkodet base64, da jeg har brugt Java til simulering af PGP, som kræver kodet form på modtagersiden, så den kan konverteres til SecretKey datatype til dekrypteringsproces.

Følg, klapp og del. Kommenter eventuelle fejl eller forbedringer eller forslag. Du kan endda følge mig på Twitter.