Простая реализация PGP на Java?

5bf55f09dd66d573639934.png5bf55f1a215c8017414796.png
Вот надо реализовать используя это MD5,RSA,DES.
  • Вопрос задан
  • 111 просмотров
Решения вопроса 1
tazhimbetov
@tazhimbetov Автор вопроса
PHP dev
package security;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.util.Scanner;
import java.util.zip.DataFormatException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class PGP {

    public static KeyPair Akeys;
    public static KeyPair Bkeys;
    static int keyLength;
    static SecretKey Sessionkey;
    static String encodedKey;
    static Cipher ecipher;
    static Cipher decipher;
    private final static char[] hexArray = "0123456789ABCDEF".toCharArray();
    static KeyPairGenerator keyGen;
    static SecretKey RSAKey;
    static Cipher CipherRSA_A;
    static Cipher DecipherRSA_A;
    static Cipher CipherRSA_B;
    static Cipher DecipherRSA_B;
    static PublicKey publicKey;

    public static void main(String args[]) throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, Exception {
        Scanner in = new Scanner(System.in);
        System.out.println("Enter the message!");

        String plaintext = in.nextLine();
        //To create keys.
        initalizeKey();
        byte[] encryptedMessage = SourceA(plaintext);
        System.out.println(DestinationB(encryptedMessage));
    }

    public static byte[] SourceA(String plaintext) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException {
        byte[] bytesOfMessage = plaintext.getBytes("UTF-8");//to byte array
        byte[] theHash = MD5(bytesOfMessage);//hashing
        byte[] EncryptedWithRsa = EncryptRSA_A(theHash);//encrypting the hash with RSA
        byte[] Concentaned = Concentane(EncryptedWithRsa, bytesOfMessage);//Concatenation
        byte[] CompressedData = compress(Concentaned);//Compressing
        byte[] EncryptedWithDes = DES(CompressedData);//Encrypting with DES
        byte[] EncryptedKeyWithRSA = EncryptRSA_B(encodedKey.getBytes("UTF-8"));//Encrypting key for DES with RSA
        byte[] result = Concentane(EncryptedKeyWithRSA, EncryptedWithDes);//Concatenation
        return result;
    }

    public static String DestinationB(byte[] MessageFromA) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException, DataFormatException {
        //Copying first 256 bytes from MessageFromA (first 256 bytes are encrypted key with rsa)
        byte[] EncriptedKeyWithRSA = new byte[256];
        System.arraycopy(MessageFromA, 0, EncriptedKeyWithRSA, 0, 256);

        //copying to EncryptedWithDes bytes after key, main message is there
        byte[] EncryptedWithDes = new byte[MessageFromA.length - 256];
        System.arraycopy(MessageFromA, 256, EncryptedWithDes, 0, MessageFromA.length - 256);

        //Decrypting the key, and decrypting main message using the DES
        byte[] decyptedKeyWithRSA = DecryptRSA_B(EncriptedKeyWithRSA);
        String decryptedKey = new String(decyptedKeyWithRSA, "UTF-8");
        byte[] fromDecryptionDES = DecryptDES(EncryptedWithDes, decryptedKey);//getting first 256 that is  with RSA than decrypting; 
        //bytes after 256's are clear mainmessage 
        // check if encrypted hash is equal to hash of mainmessage
        byte[] decomp = decompress(fromDecryptionDES);
        byte[] EncryptedHash = new byte[256];
        System.arraycopy(decomp, 0, EncryptedHash, 0, 256);
        byte[] MainMessage = new byte[decomp.length - 256];
        System.arraycopy(decomp, 256, MainMessage, 0, decomp.length - 256);
        System.out.println("Main message: " + new String(MainMessage, "UTF-8"));
        //changed to hex because it's easier to check
        return "Decrypted hash: \t" + bytesToHex(DecryptRSA_A(EncryptedHash)) + "\n" + "Hashed main message: \t" + bytesToHex(MD5(MainMessage)) + "\nif they equal ? " + bytesToHex(MD5(MainMessage)).equals(bytesToHex(DecryptRSA_A(EncryptedHash)));
    }

    public static String bytesToHex(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for (int j = 0; j < bytes.length; j++) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2] = hexArray[v >>> 4];
            hexChars[j * 2 + 1] = hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }

    public static byte[] MD5(byte[] bytesOfMessage) throws UnsupportedEncodingException, NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] thedigest = md.digest(bytesOfMessage);
        return thedigest;
    }

    public static byte[] Concentane(byte[] bytesOfMessage, byte[] fromRsa) {
        byte[] c = new byte[bytesOfMessage.length + fromRsa.length];
        System.arraycopy(bytesOfMessage, 0, c, 0, bytesOfMessage.length);
        System.arraycopy(fromRsa, 0, c, bytesOfMessage.length, fromRsa.length);
        return c;
    }

    public static byte[] compress(byte[] b) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        GZIPOutputStream zos = new GZIPOutputStream(baos);
        zos.write(b);
        zos.close();
        return baos.toByteArray();
    }

    public static byte[] decompress(byte[] b) throws IOException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ByteArrayInputStream bais = new ByteArrayInputStream(b);
        GZIPInputStream zis = new GZIPInputStream(bais);
        byte[] tmpBuffer = new byte[256];
        int n;
        while ((n = zis.read(tmpBuffer)) >= 0) {
            baos.write(tmpBuffer, 0, n);
        }
        zis.close();
        return baos.toByteArray();
    }

    private static void initalizeKey() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        //des
        Sessionkey = KeyGenerator.getInstance("DES").generateKey();
        ecipher = Cipher.getInstance("DES");
        decipher = Cipher.getInstance("DES");
        ecipher.init(Cipher.ENCRYPT_MODE, Sessionkey);
        decipher.init(Cipher.DECRYPT_MODE, Sessionkey);
        //rsa
        CipherRSA_A = Cipher.getInstance("RSA");
        DecipherRSA_A = Cipher.getInstance("RSA");
        CipherRSA_B = Cipher.getInstance("RSA");
        DecipherRSA_B = Cipher.getInstance("RSA");
        keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        Akeys = keyGen.genKeyPair();
        Bkeys = keyGen.genKeyPair();
        //encdoing the key to make it possible to sent and use again
        encodedKey = java.util.Base64.getEncoder().encodeToString(Sessionkey.getEncoded());
    }

    private static byte[] DES(byte[] CompressedData) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        byte[] encryptedDes = ecipher.doFinal(CompressedData);
        return encryptedDes;

    }

    private static byte[] EncryptRSA_B(byte[] bytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        CipherRSA_B.init(Cipher.ENCRYPT_MODE, Bkeys.getPublic());
        byte[] x = CipherRSA_B.doFinal(bytes);
        return x;
    }

    private static byte[] DecryptRSA_B(byte[] bytes) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        DecipherRSA_B.init(Cipher.DECRYPT_MODE, Bkeys.getPrivate());
        byte[] x = DecipherRSA_B.doFinal(bytes);
        return x;
    }

    public static byte[] EncryptRSA_A(byte[] messageDigest) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        CipherRSA_A.init(Cipher.ENCRYPT_MODE, Akeys.getPrivate());
        byte[] x = CipherRSA_A.doFinal(messageDigest);
        return x;
    }

    public static byte[] DecryptRSA_A(byte[] messageDigest) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
        DecipherRSA_A.init(Cipher.DECRYPT_MODE, Akeys.getPublic());
        byte[] x = DecipherRSA_A.doFinal(messageDigest);
        return x;
    }

    private static byte[] DecryptDES(byte[] fromAntiRsa, String string) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        byte[] decodedKey = java.util.Base64.getDecoder().decode(string);
        SecretKey originalKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "DES");
        Cipher de = Cipher.getInstance("DES");
        de.init(Cipher.DECRYPT_MODE, originalKey);
        byte[] res = de.doFinal(fromAntiRsa);
        return res;
    }
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы