解密加密文件

时间:2018-05-12 15:16:46

标签: java encryption keystore

我正在编写一个加密和解密文本文件的程序。 我为发件人和收件人创建了2个密钥库,并使用发件人的私钥和接收者的公钥在加密部分生成了数字签名。

该文件已加密,现在我无法解密它 - 数字签名没有被验证,虽然我转移它(和其他一些参数,如IV和密钥通过配置文件),我想我正在使用CipherInputStream错误,因为没有写入输出文件,Eclipse没有显示我任何错误。

这是我的代码,解密部分是最后一个功能

package cryptogaphy;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.KeyPair;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Base64;
import java.util.Properties;
import java.util.Scanner;


public class crypto {

    public static void main(String[] args) throws Exception {
        // Getting Alice's keyStore password for encrypting
        Scanner reader = new Scanner(System.in);  
        String aliceStorePass;
        System.out.println("In order to start the encryption, please enter Alice's Kestore password:");
        aliceStorePass = reader.next(); 
        System.out.println("aliceStorePass: " + aliceStorePass);
        encrypt(aliceStorePass);

        // Getting Bob's keyStore password for decrypting
        String bobStorePass;
        System.out.println("Now let's decrypt: Please enter Bob's Kestore password:");
        bobStorePass = reader.next(); 
        System.out.println("bobStorePass: " + bobStorePass);
        decrypt(bobStorePass);
        reader.close();
    }


    public static void encrypt(String storePass) throws Exception {

        try {

        // Generate a symmetric key
        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        SecureRandom secureRandom = new SecureRandom();
        int keyBitSize = 128;
        keyGenerator.init(keyBitSize, secureRandom);
        SecretKey symmetricKey = keyGenerator.generateKey();
        Key key = symmetricKey;
        System.out.println("Symmetric Key: " + key);

        // Generate a random IV
        SecureRandom randomSecureRandom = SecureRandom.getInstance("SHA1PRNG");
        byte[] ivByte = new byte[16];
        randomSecureRandom.nextBytes(ivByte);
        IvParameterSpec iv = new IvParameterSpec(ivByte);
        System.out.println("Random Iv: " + iv);

        // Defining the data we want to encrypt
        File plainData = new File("C:\\Users\\Victoria\\Desktop\\plainData.txt");
        File encryptedData = new File("C:\\Users\\Victoria\\Desktop\\encryptedData.txt");

        FileInputStream inputStream = new FileInputStream(plainData);
        FileOutputStream outputStream = new FileOutputStream(encryptedData);
        byte[] inputBytes = new byte[(int) plainData.length()];
        inputStream.read(inputBytes);
        inputStream.close();

        // Encrypting
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, iv, SecureRandom.getInstance("SHA1PRNG"));
        CipherOutputStream output = new CipherOutputStream(outputStream, cipher);
        output.write(inputBytes);
        output.close();
        byte curIV[] = cipher.getIV();
        String ivString = new String(curIV);
        System.out.println("ivString: " + ivString);


        // Load Alice's keyStore in order to retrieve keys 
        // Alice's private key will be used for computing a digital signature
        // Bob's public key will be used for encrypting a symmetric key
        char[] aliceStorePass = storePass.toCharArray();
        char[] aliceKeypass = "aliceKey".toCharArray();

        FileInputStream aliceInput = new FileInputStream("C:\\Users\\Victoria\\Desktop\\cryptography\\aliceKeystore.jks");
        KeyStore aliceKeystore = KeyStore.getInstance("JKS");
        aliceKeystore.load(aliceInput, aliceStorePass);

        String alias = "alice";
        String alias2 = "bobcert";

        Key aliceKey = aliceKeystore.getKey(alias, aliceKeypass);
        PublicKey bobPublicKey = null;

        // retrieve Alice's private key and Bob's public key from Alice's keyStore
        if (aliceKey instanceof PrivateKey) {
          Certificate cert = aliceKeystore.getCertificate(alias2);
          bobPublicKey = cert.getPublicKey();
          new KeyPair(bobPublicKey, (PrivateKey) aliceKey);
          System.out.println("Alice's private key: " + (PrivateKey) aliceKey);
        }
        System.out.println("Bob's public key: " + bobPublicKey);

        // Encrypt the Symmetric Key with asymmetric RSA algorithm
        byte[] encryptedkey = symmetricKey.getEncoded();
        Cipher keyCipher = Cipher.getInstance("RSA");  
        keyCipher.init(Cipher.ENCRYPT_MODE, bobPublicKey );  
        keyCipher.doFinal(encryptedkey);

        System.out.println("Asymmetric Secret Key: " + encryptedkey);

        // Computing an asymmetric digital signature of the encrypted data
        Signature sign = Signature.getInstance("SHA1withRSA"); 
        sign.initSign((PrivateKey) aliceKey);
        FileInputStream fis = new FileInputStream(encryptedData);
        BufferedInputStream bufin = new BufferedInputStream(fis);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = bufin.read(buffer)) >= 0) {
            sign.update(buffer, 0, len);
        };
        bufin.close();
        byte[] realSig = sign.sign();
        System.out.println("Signature: " + realSig);

        System.out.println("ENCRYPTION COMPLETED! check your encrypted data file\n");

        // Update configuration file
        Properties prop = new Properties();

        try {
            //set the properties value
            String keyString = Base64.getEncoder().encodeToString(symmetricKey.getEncoded());
            String encryptedkeyString = new String(encryptedkey);
            String realSigString = new String(realSig);
            prop.setProperty("iv", ivString);
            prop.setProperty("key", keyString);
            prop.setProperty("encrypted_symmetric_key", encryptedkeyString);
            prop.setProperty("signature", realSigString);
            prop.setProperty("signature_algorithm", "SHA1withRSA");

            //save properties to project root folder
            prop.store(new FileOutputStream("C:\\Users\\Victoria\\Desktop\\cryptography\\resources\\config.properties"), null);

        } catch (IOException ex) {
            ex.printStackTrace();
        }

    } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException | CertificateException e){
    System.out.println(e); 
    }
    }



    public static void decrypt(String storePass) throws Exception {

        // Load configuration file
        Properties prop = new Properties();
        InputStream input = new FileInputStream("C:\\Users\\Victoria\\Desktop\\cryptography\\resources\\config.properties");
        prop.load(input);

        // Retrieving values from configuration file
        String key = prop.getProperty("key");
        System.out.println("key: " + key);
        String iv = prop.getProperty("iv");
        System.out.println("iv: " + iv);
        String stringSignature = prop.getProperty("signature");
        System.out.println("signature: " + stringSignature);

        // Coverting to cipher applicable parameters
        byte[] keyBytes = Base64.getDecoder().decode(key);
        Key newkey = new SecretKeySpec(keyBytes,0,keyBytes.length, "AES");  

        byte[] ivBytes = iv.getBytes();
        IvParameterSpec newiv = new IvParameterSpec(ivBytes);


        // Load Bob's keyStore in order to retrieve keys 
        // Alice's public key will be used for verifying the digital signature
        // Bob's private key will be used for decrypting the data
        char[] bobStorePass = storePass.toCharArray();
        char[] bobKeypass = "bobKey".toCharArray();

        String alias = "bob";
        String alias2 = "alicecert";

        FileInputStream bobInput = new FileInputStream("C:\\Users\\Victoria\\Desktop\\cryptography\\bobKeystore.jks");
        KeyStore bobKeystore = KeyStore.getInstance("JKS");
        bobKeystore.load(bobInput, bobStorePass);

         Key bobKey = bobKeystore.getKey(alias, bobKeypass);
         PublicKey alicePublicKey = null;

        // retrieve Bob's private key and Alice's public key from Bob's keyStore
        if (bobKey instanceof PrivateKey) {
          Certificate cert = bobKeystore.getCertificate(alias2);
          alicePublicKey = cert.getPublicKey();
          new KeyPair(alicePublicKey, (PrivateKey) bobKey);
          System.out.println("Bob's private key: " + (PrivateKey) bobKey);
        }
        System.out.println("Alice's public key: " + alicePublicKey);


        File encryptedData = new File("C:\\Users\\Victoria\\Desktop\\encryptedData.txt");
        File decryptedData = new File("C:\\Users\\Victoria\\Desktop\\decryptedData.txt");
        FileInputStream inputStream = new FileInputStream(encryptedData);
        byte[] inputBytes = new byte[(int) decryptedData.length()];
        inputStream.read(inputBytes);

        // Verify digital signature
        Signature sig = Signature.getInstance("SHA1withRSA");
        sig.initVerify(alicePublicKey);
        BufferedInputStream bufin = new BufferedInputStream(inputStream);
        byte[] buffer = new byte[1024];
        int len;
        while (bufin.available() != 0) {
            len = bufin.read(buffer);
            sig.update(buffer, 0, len);
        };


        byte[] sigToVerify = stringSignature.getBytes();
        boolean verifies = sig.verify(sigToVerify);
        System.out.println("signature verifies: " + verifies);  


        // Decryption
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, newkey, newiv, SecureRandom.getInstance("SHA1PRNG"));
        CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
        FileOutputStream outputStream = new FileOutputStream(decryptedData);

        // Writing the decrypted content to an output file
        byte[] buff = new byte[1024 * 10];
        int length;
        while ((length = cipherInputStream.read(buff)) > 0) {
            outputStream.write(buff, 0, length);
        }
        bufin.close();
        outputStream.close();
        cipherInputStream.close();


}
}

对不起代码的长度,任何帮助都将不胜感激!

0 个答案:

没有答案