본문 바로가기
java

[JAVA] 파일 암호화 (Encrypt file using java)

by moonsiri 2021. 11. 1.
728x90
반응형

1. 이미지 파일 암호화/복호화

public class ImgCryptUtils {

	private int KEY = 123;  // key is act as password to Encrypt and Decrypt the Image
	private String FILE_PATH = "C:\\Users\\moonsiri\\Downloads\\photo.jpg";

	public void encrypt() throws IOException {

		// Selecting a Image for operation
		FileInputStream fis = new FileInputStream(FILE_PATH);

		// Converting Image into byte array, create a array of same size as Image size
		byte data[] = new byte[fis.available()];

		// Read the array
		fis.read(data);
		int i = 0;

		// Performing an XOR operation on each value of byte array due to which every value of Image will change.
		for (byte b : data) {
			data[i] = (byte)(b ^ KEY);
			i++;
		}

		// Opening a file for writing purpose
		FileOutputStream fos = new FileOutputStream(FILE_PATH);

		// Writing new byte array value to image which will Encrypt it.
		fos.write(data);

		// Closing file
		fos.close();
		fis.close();
		System.out.println("Encryption Done...");
	}

	public void decrypt() throws IOException {

		// Selecting a Image for Decryption.
		FileInputStream fis = new FileInputStream(FILE_PATH);

		// Converting image into byte array, it will Create a array of same size as image.
		byte data[] = new byte[fis.available()];

		// Read the array
		fis.read(data);
		int i = 0;

		// Performing an XOR operation on each value of byte array to Decrypt it.
		for (byte b : data) {
			data[i] = (byte)(b ^ KEY);
			i++;
		}

		// Opening file for writting purpose
		FileOutputStream fos = new FileOutputStream(FILE_PATH);

		// Writting Decrypted data on Image
		fos.write(data);
		fos.close();
		fis.close();
		System.out.println("Decryption Done...");
	}
}

https://www.geeksforgeeks.org/encrypt-and-decrypt-image-using-java/

 

Encrypt and Decrypt Image using Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

2. pdf 파일 암호화

        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.21</version>
        </dependency>
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.encryption.*;

@Slf4j
public class PdfCryptUtils {

	private String PASSWORD = "123abc";
	private String PDF_PATH = "C:\\Users\\moonsiri\\Downloads\\file.pdf";

	public void encrypt() {
		try {
			// step 1. Loading the pdf file
			File f = new File(PDF_PATH);
			PDDocument pdd = PDDocument.load(f);

			// step 2.Creating instance of AccessPermission class
			AccessPermission ap = new AccessPermission();

			// step 3. Creating instance of StandardProtectionPolicy
			StandardProtectionPolicy stpp = new StandardProtectionPolicy(PASSWORD, PASSWORD, ap);

			// step 4. Setting the length of Encryption key
			stpp.setEncryptionKeyLength(128);

			// step 5. Setting the permission
			stpp.setPermissions(ap);

			// step 6. Protecting the PDF file
			pdd.protect(stpp);

			// step 7. Saving and closing the the PDF Document
			pdd.save(PDF_PATH);
			pdd.close();

			log.debug("PDF Encrypted successfully...");
		} catch (InvalidPasswordException e) {
			log.debug("이미 비밀번호 설정이 되어있음");
		} catch (IOException e) {
			log.error("오류 발생");
		}
	}

}

https://www.geeksforgeeks.org/encrypt-and-decrypt-image-using-java/

 

Encrypt and Decrypt Image using Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

 

3. zip 파일 암호화

<dependency>
    <groupId>net.lingala.zip4j</groupId>
    <artifactId>zip4j</artifactId>
    <version>2.10.0</version>
</dependency>
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.EncryptionMethod;

import java.io.File;
import java.util.Arrays;
import java.util.List;

public class ZipCryptUtils {

	private String PASSWORD = "123a";
	private String IMAGE_PATH = "C:\\Users\\moonsiri\\Downloads\\photo.jpg";
	private String PDF_PATH = "C:\\Users\\moonsiri\\Downloads\\file.pdf";
	private String EXCEL_PATH = "C:\\Users\\moonsiri\\Downloads\\test.xlsx";

	private String CREATE_ZIP_PATH = "C:\\Users\\moonsiri\\Downloads\\test.zip";
	private String DOWNLOAD_ZIP_FOLDER = "C:\\Users\\moonsiri\\Downloads\\zip\\";

	public void encrypt() {

		// Try block to check if any exception occurs
		try {

			// Creating encryption zipParameters
			// for password protection
			ZipParameters zipParameters = new ZipParameters();

			// Setting encryption files
//			zipParameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
//			zipParameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);

			// Setting encryption of files to true
			zipParameters.setEncryptFiles(true);

			// Setting encryption method
			zipParameters.setEncryptionMethod(EncryptionMethod.AES);

			// Set the key strength
			zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);

			// *********CREATE ZIP FILE***************

			// Creating list of files to be added to ZIP file And Add SPECIFIC files
			List<File> list = Arrays.asList(
				new File(IMAGE_PATH),
				new File(PDF_PATH),
				new File(EXCEL_PATH)
			);

			// Creating ZIP file And Set the password
			ZipFile zipFile = new ZipFile(CREATE_ZIP_PATH, PASSWORD.toCharArray());

			// Pass and ZIP parameters
			// for Zip file to be created
			zipFile.addFiles(list, zipParameters);

			// Print the destination in the local directory
			// where ZIP file is created
			System.out.println("Password protected Zip file have been created at "  + CREATE_ZIP_PATH);

			// Catch block to handle the exceptions
		} catch (ZipException e) {

			// Print the exception and line number
			// where tit occurred
			e.printStackTrace();
		}
	}

	public void decrypt() {
		LocalFileHeader localFileHeader;
		int readLen;
		byte[] readBuffer = new byte[4096];

		// 암호해제 + 압축해제
		try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(ZIP_PATH), PASSWORD.toCharArray())) {
			while ((localFileHeader = zipInputStream.getNextEntry()) != null) {
				File extractedFile = new File(DOWNLOAD_ZIP_FOLDER + localFileHeader.getFileName());
				try (OutputStream outputStream = new FileOutputStream(extractedFile)) {
					while ((readLen = zipInputStream.read(readBuffer)) != -1) {
						outputStream.write(readBuffer, 0, readLen);
					}
				}
			}
		} catch (IOException e) {

			e.printStackTrace();
		}

	}
}

https://www.geeksforgeeks.org/create-password-protected-zip-file-in-java/

 

Create Password Protected Zip File in Java - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

https://github.com/srikanth-lingala/zip4j

 

GitHub - srikanth-lingala/zip4j: A Java library for zip files and streams

A Java library for zip files and streams. Contribute to srikanth-lingala/zip4j development by creating an account on GitHub.

github.com

 

3.1. MultipartFile을 zip 압축 후 S3에 업로드 / S3에서 다운로드 후 unzip

public void upload(MultipartFile mpFile) throws IOException {
    ZipParameters zipParameters = new ZipParameters();
    zipParameters.setEncryptFiles(true);
    zipParameters.setEncryptionMethod(EncryptionMethod.AES);
    zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);

    String orgFileName = mpFile.getOriginalFilename();
    String zipFileName = orgFileName + zipExt;
    
    final String fileTempPath = FILE_TEMP_PATH + orgFileName;
    final String zipFileTempPath = FILE_TEMP_PATH + zipFileName;
    try (ZipFile zipFile = new ZipFile(zipFileTempPath, PASSWORD.toCharArray())) {
        File file = new File(fileTempPath);
        file.createNewFile();
        FileOutputStream fos = new FileOutputStream(file);
        fos.write(mpFile.getBytes());
        fos.close();
        zipFile.addFile(file, zipParameters);

        return Files.newInputStream(Path.of(zipFileTempPath));
    } catch (IOException e) {
        throw new RuntimeException("zip file 생성 시 오류 발생");
    } finally {
        FileUtils.deleteQuietly(new File(fileTempPath)); // 원본 파일 삭제
        FileUtils.deleteQuietly(new File(zipFileTempPath)); // 원본 파일 삭제
    }
    
    ObjectMetadata objMeta = new ObjectMetadata();
    MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
    objMeta.setContentType(mimeTypesMap.getContentType(zipFileName));
    PutObjectRequest putObjReq = new PutObjectRequest(BUCKET_NAME, prefixKey + SEPERATOR_SLASH + zipFileName, inputStream, objMeta);
    amazonS3Client.putObject(putObjReq);
}

public void download(HttpServletResponse response) throws IOException {
    // start: S3 임시 url 생성
    Date expiredDate = DateUtil.getDateFromString(DateUtil.addMinute(DateUtil.getNow(), 5));
    GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, fileUploadPathInS3).withMethod(HttpMethod.GET).withExpiration(expiredDate);
    URL url = amazonS3Client.generatePresignedUrl(generatePresignedUrlRequest);
    String downloadUrl = url.toString();
    // end: S3 임시 url 생성 (private S3가 아니라면 public 주소를 사용하면 됨
    
    disableSslVerification();
    URL awss3Url = new URL(downloadUrl);
    URLConnection urlConnection = awss3Url.openConnection();
    urlConnection.setConnectTimeout(3000);
    urlConnection.setReadTimeout(3000);

    int contentLength = urlConnection.getContentLength();
    if (contentLength <= 0) {
        return;
    }

    try (InputStream inputStream = urlConnection.getInputStream();
        OutputStream outputStream = response.getOutputStream();
        ZipInputStream zipInputStream = new ZipInputStream(inputStream, PASSWORD.toCharArray())) {

        LocalFileHeader localFileHeader = zipInputStream.getNextEntry();	// 파일이 하나만 존재한다는 전제하에
        String fileName = localFileHeader.getFileName();
        String ext = FilenameUtils.getExtension(fileName);
        if (Arrays.asList("png", "bmp", "jpg", "jpeg").stream().anyMatch(ext::equalsIgnoreCase)) {
            response.setContentType("image/" + ext.toLowerCase());
            response.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
        } else {
            response.setContentType("APPLICATION/OCTET-STREAM");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
        }

        byte[] buffer = new byte[4096];
        int numBytesRead;
        while ((numBytesRead = zipInputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, numBytesRead);
        }
    }
}

/**
 * 유효하지 않은 SSL 인증서를 사용하는 서버에 접근하도록 HttpURLConnection 를 설정
 */
private void disableSslVerification() {
    try {
        // Create a trust manager that does not validate certificate chains
        TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };

        // Install the all-trusting trust manager
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };

        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    } catch (NoSuchAlgorithmException | KeyManagementException e) {
        e.printStackTrace();
    }
}

 

 

4. excel 파일 암호화

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.1</version>
        </dependency>
import org.apache.poi.openxml4j.exceptions.*;
import org.apache.poi.openxml4j.opc.*;
import org.apache.poi.poifs.crypt.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

@Slf4j
public class ExcelCryptUtils {

	private String PASSWORD = "123abc";
	private String EXCEL_PATH = "C:\\Users\\moonsiri\\Downloads\\test.xlsx";

	public void encrypt() {

		try (POIFSFileSystem fs = new POIFSFileSystem()) {
			EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
			// EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile, CipherAlgorithm.aes192, HashAlgorithm.sha384, -1, -1, null);
			Encryptor enc = info.getEncryptor();
			enc.confirmPassword(PASSWORD);

			// Read in an existing OOXML file and write to encrypted output stream don't forget to close the output stream otherwise the padding bytes aren't added
			try (
				OPCPackage opc = OPCPackage.open(new File(EXCEL_PATH), PackageAccess.READ_WRITE);
				OutputStream os = enc.getDataStream(fs)
			) {
				opc.save(os);
			} catch (OLE2NotOfficeXmlFileException e) {
				log.debug("암호화 되어있음.");
			} catch (GeneralSecurityException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (InvalidFormatException e) {
				e.printStackTrace();
			}

			// Write out the encrypted version
			try (FileOutputStream fos = new FileOutputStream(EXCEL_PATH)) {
				fs.writeFilesystem(fos);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
}

https://poi.apache.org/encryption.html

 

Apache POI - Encryption support

Apache POI - Encryption support Overview Apache POI contains support for reading few variants of encrypted office files: Binary fo

poi.apache.org

 

5. File Aes256 암호화

암호화 시간이 너무 오래 걸림

@Slf4j
public class FileAes256Util {

	private static String KEY = "9003e5a13d69a78c0d8210cb28b9d0d38e5445568899f637c24bc08241f98ded";
//	private static String IV = "024e54561023da13118d16ac21119b8a";

	private String IMAGE_PATH = "C:\\Users\\moonsiri\\Downloads\\photo2.jpg";
	private String PDF_PATH = "C:\\Users\\moonsiri\\Downloads\\file2.pdf";
	private String uploadFile = IMAGE_PATH;

	public void aes256Encode() throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {

		byte[] _key = hexStringToByteArray(KEY);

		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		SecretKeySpec keyspc = new SecretKeySpec(_key, "AES");
		cipher.init(Cipher.ENCRYPT_MODE, keyspc);
		byte[] iv = cipher.getIV();

		try (
			InputStream input = new BufferedInputStream(new FileInputStream(uploadFile));
			FileOutputStream fileOut = new FileOutputStream(uploadFile);
			CipherOutputStream cipherOut = new CipherOutputStream(fileOut, cipher);
		) {
			fileOut.write(iv);

			byte[] buffer = new byte[1024];
			int read;
			while ((read = input.read(buffer)) != -1) {
				cipherOut.write(cipher.update(buffer, 0, read));
			}
			cipherOut.write(cipher.doFinal());
		} catch (Exception e) {
			System.exit(0);
		}
	}

	public void aes256Decode() throws NoSuchPaddingException, NoSuchAlgorithmException {
		byte[] _key = hexStringToByteArray(KEY);
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		SecretKeySpec keyspc = new SecretKeySpec(_key, "AES");

		try (
			FileInputStream fileIn = new FileInputStream(uploadFile)
		) {
			byte[] fileIv = new byte[16];
			fileIn.read(fileIv);
			cipher.init(Cipher.DECRYPT_MODE, keyspc, new IvParameterSpec(fileIv));

			try (
				CipherInputStream cipherIn = new CipherInputStream(fileIn, cipher);
				InputStreamReader inputReader = new InputStreamReader(cipherIn);
				BufferedReader reader = new BufferedReader(inputReader)
			) {

				// TODO read

			}

		} catch (Exception e) {
		}
	}

	private static byte[] hexStringToByteArray(String s) {
		int len = s.length();
		byte[] data = new byte[len / 2];
		for (int i = 0; i < len; i += 2) {
			data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
		}
		return data;
	}
}

https://www.baeldung.com/java-cipher-input-output-stream

 

Encrypting and Decrypting Files in Java | Baeldung

Use CipherInputStream and CipherOutputStream classes to encrypt and decrypt files in Java.

www.baeldung.com

 

728x90
반응형

댓글