Java >> Java Program >  >> Java

Java RSA-kryptering och dekryptering Exempel | ECB-läge + 4096 bitar + OAEPWITHSHA-512ANDMGF1PADDING

RSA [R ivest S hamir A dleman] är en stark kryptering och dekryptering algoritm som använder public key kryptografi . RSA-algoritm är en asymmetrisk kryptografialgoritm, till skillnad från symmetrisk algoritm som använder samma nyckel för både kryptering och dekryptering kommer vi att använda två olika nycklar. En nyckel kan ges till vem som helst [Public Key] och den andra nyckeln ska hållas privat [Privat nyckel] .

I den här artikeln kommer vi att diskutera RSA-kryptering och dekryptering i Java med OAEPWITHSHA-512ANDMGF1PADDING utfyllnad och 4096 Bitnyckel.

Vad är RSA-kryptering?

RSA-krypteringsalgoritm publicerades på 70-talet av Ron R ivest, Adi S hamir och Leonard A dleman. Det är den mest använda kryptografialgoritmen för offentliga nyckel i världen och baserad på svårigheten att faktorisera stora heltal.

Den kan användas för att kryptera ett meddelande utan att behöva byta ut en hemlig nyckel separat. RSA stöder nyckellängd på 1024, 2048, 3072, 4096 7680 och 15360 bitar .

Exempel på Java RSA-kryptering och dekryptering

Låt oss säga om John och Smith vill utbyta ett meddelande och använda RSA kryptering sedan,

  • Innan du skickar meddelandet, John måste känna till Public Key av Smith . Använda den offentliga nyckeln , John krypterar meddelandet och skickar det krypterade meddelandet till Smith .
  • Smith kan använda sin privata nyckel för att enkelt dekryptera meddelandet.
package com.javainterviewpoint;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;

import javax.crypto.Cipher;

public class RSA_Encryption
{
    static String plainText = "Plain text which need to be encrypted by Java RSA Encryption in ECB Mode";
    
    public static void main(String[] args) throws Exception
    {
        // Get an instance of the RSA key generator
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(4096);
        
        // Generate the KeyPair
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        
        // Get the public and private key
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        
        System.out.println("Original Text  : "+plainText);
        
        // Encryption
        byte[] cipherTextArray = encrypt(plainText, publicKey);
        String encryptedText = Base64.getEncoder().encodeToString(cipherTextArray);
        System.out.println("Encrypted Text : "+encryptedText);
        
        // Decryption
        String decryptedText = decrypt(cipherTextArray, privateKey);
        System.out.println("DeCrypted Text : "+decryptedText);
    }
    
    public static byte[] encrypt (String plainText,PublicKey publicKey ) throws Exception
    {
        //Get Cipher Instance RSA With ECB Mode and OAEPWITHSHA-512ANDMGF1PADDING Padding
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING");
        
        //Initialize Cipher for ENCRYPT_MODE
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        
        //Perform Encryption
        byte[] cipherText = cipher.doFinal(plainText.getBytes()) ;

        return cipherText;
    }
    
    public static String decrypt (byte[] cipherTextArray, PrivateKey privateKey) throws Exception
    {
        //Get Cipher Instance RSA With ECB Mode and OAEPWITHSHA-512ANDMGF1PADDING Padding
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING");
        
        //Initialize Cipher for DECRYPT_MODE
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        
        //Perform Decryption
        byte[] decryptedTextArray = cipher.doFinal(cipherTextArray);
        
        return new String(decryptedTextArray);
    }
}
  • KeyPairGenerator Klass används för att generera asymmetriska krypteringsnycklar [offentliga och privata nycklar] , får vi KeyPairGenerator instans genom att anropa getInstance() metod som skickar namnet på algoritmen som en parameter, i vårt fall är det RSA
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
  • Vi måste initiera KeyPairGenerator instans skapas ovan genom att anropa dess initialize() metod måste vi ange storleken på nycklarna för att generera. Vi har passerat 4096 , när vi skapar 4096 bitnyckel.
keyPairGenerator.initialize(4096);
  • När KeyPairGenerator  initieras, kan vi generera PublicKey och PrivateKey  genom att anropa generateKeyPair() metod ovanpå KeyPairGenerator  instans.
  • getPublic() metod returnerar PublicKey och getPrivate() metod returnerar PrivateKey
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
  • Chiffer är klassen som hanterar den faktiska krypteringen och dekrypteringen. Förekomsten av Chifferet klass skapas genom att anropa getInstance() metod som Chiffernamn skickas som en parameter, chiffernamnet består av 3 delar
    • Den första delen är namnet på algoritmen, i vårt fall är det RSA
    • Den andra delen är det läge som algoritmen ska användas i – ECB. ”ECB” är ett symmetriskt chifferläge och RSA är ett asymmetriskt chiffer , Så "ECB" har ingen effekt
    • Den tredje delen är utfyllnadsschemat som kommer att användas – OAEPWITHSHA-512ANDMGF1PADDING
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING");
  • Vi måste initiera Chifferet för att utföra krypteringen eller dekrypteringen, kringgå läget och tangenten .
    • Chifferläge kan Chiffer.ENCRYPT_MODE för Kryptering eller Chiffer.DECRYPT_MODE för Dekryptering
    • PublicKey  för Kryptering eller PrivateKey  för Dekryptering
cipher.init(Cipher.ENCRYPT_MODE, publicKey);

eller

cipher.init(Cipher.DECRYPT_MODE, privateKey);
  • En gång efter Läge och nyckel är inställd på Chiffer
    • För att kryptera , måste vi klara PlainText som en parameter till doFinal() metoden för Chiffer Förekomst
byte[] cipherText = cipher.doFinal(plainText.getBytes()) ;
String encryptedText = Base64.getEncoder().encodeToString(cipherTextArray);
    • För att Dekryptera,  vi måste skicka chiffertexten som en parameter till doFinal() metoden för Chiffer instans
byte[] decryptedTextArray = cipher.doFinal(cipherTextArray);

Utdata:

Original Text  : Plain text which need to be encrypted by Java RSA Encryption in ECB Mode
Encrypted Text : uce+oEhtismUZwJ0GjWb+C8u+RqXm7WGyJAinTzgY19H9wKHvVhk0PzQ0LH3xByudag1cYuFOej882yYnW73jPMo9aZhiCEaccy702jaTeeLhw9jB56coH71OxMxJI1xWlX/vVmqkmT8TCJEDOZZgdxtq8nyW36SDR1negt6YkBLN05A9dm8FIXVxdDgSpioWL+mkZ7QdTgtqCUZEb4d2TWb77Tu55okhKqIOwvQ3YSCe0mKpfYQ5uOaMCcVL6mqwJmI0uRB0Ja6uxlIE1WpZKzv2Hn1MQ7psc1tsVUF3B0NLK38Qb/A5m2CRB/9L5dhQTzBAC5pU5CnCgHhiE9Ms/3wp6a60FQfph26ibIKKhG37DsUJAX6p0jIhulYkuWJXT0Z87UhM11dSDIMIjcFV00R7NvmRycGu3DiDsxK06c7Yt9Ep6n8PyBoI6lMN7kKdtWD5HwGdU6OIeNluaLoAAxDUtUX1gQN//3o+aol29G6xJf42VsbG/g/7tgGDlWVoEuTR97vhdKWoq8w3XZKIsiDU+kHIjE3Z22MxLOW0w7nmGbX6bU6GZUUZBBkhcW2bjReKieGCB3acMDBGl5getpyaKK4Vt+HMiUwhTfRbarDA8itggjxlw4nmXrAAShXT4MgO9kxRSmUqfOAkKx9gNIApycNEtWukDmJuYtKXU4=
DeCrypted Text : Plain text which need to be encrypted by Java RSA Encryption in ECB Mode

Spara RSA-algoritmen offentlig och privat nyckel

I realtid kan vi inte behålla nycklarna som sådana måste vi skriva den Public Key och Privat nyckel till en fil för att spara nycklarna vi måste få modulen och exponent av båda nycklarna och skriv det till nyckelfilen.

KeyFactory keyFactory = KeyFactory.getInstance("RSA");
RSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);
RSAPrivateKeySpec privateKeySpec = keyFactory.getKeySpec(privateKey, RSAPrivateKeySpec.class);
saveKeyToFile("public.key", publicKeySpec.getModulus(), publicKeySpec.getPublicExponent());
saveKeyToFile("private.key", privateKeySpec.getModulus(), privateKeySpec.getPrivateExponent());
  • Hämta instansen av KeyFactory klass genom att anropa getInstance() metod och skicka ”RSA” som en parameter
  • När vi har fått KeyFactor instans, då kan vi få den individuella Spec-klassen [RSAPublicKeySpec , RSAPrivateKeySpec ] genom att skicka respektive nyckel och KeySpec klass.
public static void saveKeyToFile(String fileName, BigInteger modulus, BigInteger exponent) throws IOException
{
    ObjectOutputStream ObjOutputStream = new ObjectOutputStream(
        new BufferedOutputStream (new FileOutputStream(fileName)));
    try
    {
       ObjOutputStream.writeObject(modulus);
       ObjOutputStream.writeObject(exponent);
    } catch (Exception e)
    {
       e.printStackTrace();
    } finally
    {
        ObjOutputStream.close();
    }
}
  • Äntligen kan vi spara modulen och exponent som kan erhållas från respektive KeySpec klass med serialisering. Skapa ObjectOutputStream objekt och skriv modulen och exponent med hjälp av writeObject() metod.

Läser RSA-nyckel från fil

  • Skapa ObjectInputStream objekt för att läsa nyckelfilen
InputStream inputStream = new FileInputStream (keyFileName);
ObjectInputStream objectInputStream = new ObjectInputStream (new BufferedInputStream(inputStream));
  • Hämta modulen och exponent med hjälp av readObject() metod
BigInteger modulus = (BigInteger) objectInputStream.readObject();
BigInteger exponent = (BigInteger) objectInputStream.readObject();
  • Hämta instansen av KeyFactory klass genom att anropa getInstance() metod och skicka ”RSA” som en parameter
KeyFactory keyFactory = KeyFactory.getInstance("RSA")
  • Om nyckelfilen börjar med "public" anrop sedan generatePublic() metod som klarar modul och exponent annars anropa generatePrivate() metod för att få offentligheten och privat nyckel respektive.
if (keyFileName.startsWith("public"))
    key = keyFactory.generatePublic(new RSAPublicKeySpec(modulus, exponent));
else
    key = keyFactory.generatePrivate(new RSAPrivateKeySpec(modulus, exponent));

Slutligen, sätt ihop allt

package com.javainterviewpoint;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;

import javax.crypto.Cipher;

public class RSA_Read_Write_Key
{
    static String plainText = "Plain text which need to be encrypted by Java RSA Encryption in ECB Mode";

    public static void main(String[] args) throws Exception
    {
        // Get an instance of the RSA key generator
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(4096);

        // Generate the KeyPair
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        // Get the public and private key
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        
        // Get the RSAPublicKeySpec and RSAPrivateKeySpec
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        RSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(publicKey, RSAPublicKeySpec.class);
        RSAPrivateKeySpec privateKeySpec = keyFactory.getKeySpec(privateKey, RSAPrivateKeySpec.class);
        
        // Saving the Key to the file
        saveKeyToFile("public.key", publicKeySpec.getModulus(), publicKeySpec.getPublicExponent());
        saveKeyToFile("private.key", privateKeySpec.getModulus(), privateKeySpec.getPrivateExponent());

        System.out.println("Original Text  : " + plainText);

        // Encryption
        byte[] cipherTextArray = encrypt(plainText, "D:\\sts-3.8.3.RELEASE\\Workspace\\Encryption\\public.key");
        String encryptedText = Base64.getEncoder().encodeToString(cipherTextArray);
        System.out.println("Encrypted Text : " + encryptedText);

        // Decryption
        String decryptedText = decrypt(cipherTextArray, "D:\\sts-3.8.3.RELEASE\\Workspace\\Encryption\\private.key");
        System.out.println("DeCrypted Text : " + decryptedText);

    }

    public static void saveKeyToFile(String fileName, BigInteger modulus, BigInteger exponent) throws IOException
    {
        ObjectOutputStream ObjOutputStream = new ObjectOutputStream(
                new BufferedOutputStream(new FileOutputStream(fileName)));
        try
        {
            ObjOutputStream.writeObject(modulus);
            ObjOutputStream.writeObject(exponent);
        } catch (Exception e)
        {
            e.printStackTrace();
        } finally
        {
            ObjOutputStream.close();
        }
    }

    public static Key readKeyFromFile(String keyFileName) throws IOException
    {
        Key key = null;
        InputStream inputStream = new FileInputStream(keyFileName);
        ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(inputStream));
        try
        {
            BigInteger modulus = (BigInteger) objectInputStream.readObject();
            BigInteger exponent = (BigInteger) objectInputStream.readObject();
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            if (keyFileName.startsWith("public"))
                key = keyFactory.generatePublic(new RSAPublicKeySpec(modulus, exponent));
            else
                key = keyFactory.generatePrivate(new RSAPrivateKeySpec(modulus, exponent));

        } catch (Exception e)
        {
            e.printStackTrace();
        } finally
        {
            objectInputStream.close();
        }
        return key;
    }

    public static byte[] encrypt(String plainText, String fileName) throws Exception
    {
        Key publicKey = readKeyFromFile("public.key");

        // Get Cipher Instance
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING");

        // Initialize Cipher for ENCRYPT_MODE
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        // Perform Encryption
        byte[] cipherText = cipher.doFinal(plainText.getBytes());

        return cipherText;
    }

    public static String decrypt(byte[] cipherTextArray, String fileName) throws Exception
    {
        Key privateKey = readKeyFromFile("private.key");

        // Get Cipher Instance
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-512ANDMGF1PADDING");

        // Initialize Cipher for DECRYPT_MODE
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        // Perform Decryption
        byte[] decryptedTextArray = cipher.doFinal(cipherTextArray);

        return new String(decryptedTextArray);
    }
}

Utdata:

Original Text  : Plain text which need to be encrypted by Java RSA Encryption in ECB Mode
Encrypted Text : RQal6CxZAtuOU3kusg3s19FQhLrczjHq4i8wkRBh8nG0+j7mGP3LPq65mBfC8jrqTNSmdhmGyx42OzrIXaOCIfU3vw4irfmi7OpxIA7ymLIcy5L3wh/KEAfzTJhecM0r5513h/oviAYhwATkvpgsnWeOPTgCvMaoOgzULYJekEXsvmOr0mZv5ECrZa1Zj+5GQzK6Vz5MpeOHy/giPpnlQK9TIYI1KbD/2dFHYDqoeKFQ6KlaIt1VMyAzIm2FZ2GSKcqq2HRbCri+iS5xpGht8fDpLthPizvVlls5T/67341GyaKR8s+jumOQvsqB011R/TvzUY7OXquxHICqMW+UBMPoO0c92jisxyWiyHoT376KKZxuY2//Z3MRFmw/LKNaacD3OIqGjU5bnZbhMMF5QL8jLclJ7JQbxadqwCnOcaW7t2XPdYOtND1xGB4vg/eEfuCq1PytoGTTsKjnZfjozX3Mka7MIcVxKiYO0A/LksnI/sQMoZx1yNE3b6qs+v2rW0gsRLLE/DYcKczPxi1QPMqRphvKr3j93IvfNCt/V+cUdwOLM0O0Yrm5Hmsk8ggdBPlCzv7NxrglOhUDtKa6RPxQgzxAX54LkrjB8/h+I24CYNaKiFuCx5CJxeagaujEa/9uGMf6vkRWUW7CW3Gdpo5abedJmGsTNFHd6KYhZqo=
DeCrypted Text : Plain text which need to be encrypted by Java RSA Encryption in ECB Mode

Java-tagg