Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
258 views
in Technique[技术] by (71.8m points)

encryption - Java Decryption creating additional symbols

I'm writing a encryption and decryption code as follows

import java.io.*;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.BadPaddingException;
import java.nio.file.Files;
import java.util.Scanner;

public class EncryptFile
{
    public static void main(String args[]) throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException {
//Encrypt Mode
        FileOutputStream outputStream = new FileOutputStream(new File("D:\encryptedNewStringFile.txt"));
        Key secretKey = new SecretKeySpec("encKey".getBytes(), "Blowfish");
        Cipher cipher = Cipher.getInstance("Blowfish");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] getFileBytes = "writing a file using encryption ".getBytes();
        byte[] outputBytes = cipher.doFinal(getFileBytes);
        outputStream.write(outputBytes);
        getFileBytes = "
".getBytes();
        outputBytes = cipher.doFinal(getFileBytes);
        outputStream.write(outputBytes);
        getFileBytes = "This is New Line 2 
This is NewLine 3".getBytes();
        outputBytes = cipher.doFinal(getFileBytes);
        outputStream.write(outputBytes);
        outputStream.close();
//Decrypt Mode
        File curFile = new File("D:\encryptedNewStringFile.txt");
        secretKey = new SecretKeySpec("encKey".getBytes(), "Blowfish");
        cipher = Cipher.getInstance("Blowfish/ECB/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        getFileBytes = Files.readAllBytes(curFile.toPath());
        outputBytes = cipher.doFinal(getFileBytes);
        InputStream bai = new ByteArrayInputStream(outputBytes);
        BufferedReader bfReader = new BufferedReader(new InputStreamReader(bai));
        Scanner scan = new Scanner(bfReader);
        while(scan.hasNextLine())
        {
            System.out.println(scan.nextLine());
        }
}
}

here i have a problem in output which is the printed output has some extra symbols (i.e question marks and box symbols)in it.
The output i received is
enter image description here

Any suggestions will be really helpful thanks in advance


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Combining the answers from @Artjom B. and @The 5th column mouse you get a file encryption program that will encrypt a file with Blowfish in CBC mode. The encryption and decryption is done in chunks so large files (up to some GB) could get encrypted and decrypted without "out of memory errors".

The key is generated randomly, and you should keep in mind - without knowledge of the key no decryption of the file is possible.

output:

file encryption with Blowfish CBC mode
used key (Base64): jsErS04so1NCC7Jmds6Grr+0tPkNoaj0hx/izLaW5H8=
result encryption: true
result decryption: true

Security warning: the code has no exception handling, no correct file handling (e.g. overwriting without notice) and is for educational purpose only:

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;

public class BlowfishCbcFileEncryption {
    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, IOException,
            InvalidKeyException, InvalidAlgorithmParameterException {
        System.out.println("file encryption with Blowfish CBC mode");

        String uncryptedFilename = "uncrypted.txt";
        String encryptedFilename = "encrypted.enc";
        String decryptedFilename = "decrypted.txt";

        // random blowfish 256 key
        byte[] key = new byte[32];
        SecureRandom secureRandom = new SecureRandom();
        secureRandom.nextBytes(key);
        System.out.println("used key (Base64): " + base64Encoding(key));

        // random iv
        byte[] iv = new byte[8]; // blowfish iv is 8 bytes long
        secureRandom.nextBytes(iv);

        boolean result;
        result = encryptCbcFileBufferedCipherOutputStream(uncryptedFilename, encryptedFilename, key, iv);
        System.out.println("result encryption: " + result);
        result = decryptCbcFileBufferedCipherInputStream(encryptedFilename, decryptedFilename, key);
        System.out.println("result decryption: " + result);

    }

    public static boolean encryptCbcFileBufferedCipherOutputStream(String inputFilename, String outputFilename, byte[] key, byte[] iv)
            throws IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
        try (FileInputStream in = new FileInputStream(inputFilename);
             FileOutputStream out = new FileOutputStream(outputFilename);
             CipherOutputStream encryptedOutputStream = new CipherOutputStream(out, cipher);) {
            out.write(iv);
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "Blowfish");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            byte[] buffer = new byte[8096];
            int nread;
            while ((nread = in.read(buffer)) > 0) {
                encryptedOutputStream.write(buffer, 0, nread);
            }
            encryptedOutputStream.flush();
        }
        if (new File(outputFilename).exists()) {
            return true;
        } else {
            return false;
        }
    }

    public static boolean decryptCbcFileBufferedCipherInputStream(String inputFilename, String outputFilename, byte[] key) throws
            IOException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException {
        byte[] iv = new byte[8]; // blowfish iv is 8 bytes long
        Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding");
        try (FileInputStream in = new FileInputStream(inputFilename); // i don't care about the path as all is local
             CipherInputStream cipherInputStream = new CipherInputStream(in, cipher);
             FileOutputStream out = new FileOutputStream(outputFilename)) // i don't care about the path as all is local
        {
            byte[] buffer = new byte[8192];
            in.read(iv);
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "Blowfish");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
            int nread;
            while ((nread = cipherInputStream.read(buffer)) > 0) {
                out.write(buffer, 0, nread);
            }
            out.flush();
        }
        if (new File(outputFilename).exists()) {
            return true;
        } else {
            return false;
        }
    }

    private static String base64Encoding(byte[] input) {
        return Base64.getEncoder().encodeToString(input);
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...