Java tutorial
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.projectsontracks.model; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.NoSuchAlgorithmException; import java.util.List; import java.util.UUID; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import net.lingala.zip4j.core.ZipFile; import net.lingala.zip4j.exception.ZipException; import net.lingala.zip4j.io.ZipInputStream; import net.lingala.zip4j.model.FileHeader; import net.lingala.zip4j.model.ZipParameters; import net.lingala.zip4j.util.Zip4jConstants; import org.apache.commons.lang3.StringUtils; /** * * @author lionel */ public class CaribooKey { private static final String KEY_FILE_EXTENSION = "txt"; public static final int AES_DEFAULT_SIZE = 256; public final Cipher aesCipher; private int size; private byte[] key; private SecretKeySpec keySpec; public CaribooKey() throws NoSuchAlgorithmException, NoSuchPaddingException { // create AES shared key cipher this.aesCipher = Cipher.getInstance("AES"); this.size = AES_DEFAULT_SIZE; } public int getSize() { return size; } public void setSize(int size) { this.size = size; } public byte[] getKey() { return key; } public void setKey(byte[] key) { this.key = key; } public SecretKeySpec getKeySpec() { return keySpec; } public void setKeySpec(SecretKeySpec keySpec) { this.keySpec = keySpec; } /** * Creates a new AES key * * @throws java.security.NoSuchAlgorithmException */ public void createKey() throws NoSuchAlgorithmException { // Initialize the key generator KeyGenerator kgen = KeyGenerator.getInstance("AES"); kgen.init(this.size); // Generates the key SecretKey skey = kgen.generateKey(); // Returns the key in its primary encoding format, or null if this key does not support encoding. key = skey.getEncoded(); //used to construct a SecretKey from a byte array, without having to go through a (provider-based) SecretKeyFactory. keySpec = new SecretKeySpec(key, "AES"); }//createKey /** * Creates a new AES key but one that is user friendly * * @throws java.security.NoSuchAlgorithmException */ public void createUserFriendlyKey() throws NoSuchAlgorithmException { // Initialize the key generator String id = UUID.randomUUID().toString().toUpperCase().substring(0, 32); key = id.getBytes(); //used to construct a SecretKey from a byte array, without having to go through a (provider-based) SecretKeyFactory. keySpec = new SecretKeySpec(key, "AES"); }//createKey /** * Open an AES key stored in an encrypted and password protected ZIP file * Then store the key in local variable byte[] key * * @param inputFileName * @param password * @throws java.security.GeneralSecurityException * @throws java.io.FileNotFoundException * @throws net.lingala.zip4j.exception.ZipException * @throws com.projectsontracks.model.CaribooException */ public void loadKey(String inputFileName, String password) throws GeneralSecurityException, FileNotFoundException, IOException, ZipException, CaribooException { // read private key to be used to decrypt the AES key // Name of the file inside the ZIP String keyFileName = StringUtils.substringBeforeLast(inputFileName, ".") + "." + KEY_FILE_EXTENSION; keyFileName = StringUtils.substringAfterLast(keyFileName, "\\"); // Initiate ZipFile object with the path/name of the zip file. ZipFile zipFile = new ZipFile(inputFileName); //System.out.println("ZIP Key file: " + inputFileName); //System.out.println("Key file: " + keyFileName); ZipParameters parameters = new ZipParameters(); //parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // set compression method to store compression //parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); if (zipFile.isEncrypted()) { zipFile.setPassword(password); } //parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES); //parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256); //Get a list of FileHeader. FileHeader is the header information for all the files in the ZipFile List fileHeaderList = zipFile.getFileHeaders(); // Loop through all the fileHeaders for (int i = 0; i < fileHeaderList.size(); i++) { FileHeader fileHeader = (FileHeader) fileHeaderList.get(i); if (fileHeader != null) { String fileName = fileHeader.getFileName(); //System.out.println(" Zip contains : " + fileName); if (keyFileName != null && keyFileName.equalsIgnoreCase(fileName)) { //Get the InputStream from the ZipFile ZipInputStream is = zipFile.getInputStream(fileHeader); File file = new File(fileName); // read the InputStream int readLen = -1; byte[] buff = new byte[32]; while ((readLen = is.read(buff)) != -1) { } // Assign to local variable this.key = buff; keySpec = new SecretKeySpec(this.key, "AES"); //System.out.println("Key: " + new String(this.key)); } else { throw new CaribooException(fileName + " does not match " + keyFileName); } } } //for }//loadKey /** * Encrypts the AES key into a password protected ZIP file * * @param outputFile * @param password * @throws java.io.IOException * @throws java.security.GeneralSecurityException * @throws net.lingala.zip4j.exception.ZipException * @throws com.projectsontracks.model.CaribooException */ public void saveKey(String outputFile, String password) throws IOException, GeneralSecurityException, ZipException, CaribooException { // write AES key String tmpFileName = StringUtils.substringBeforeLast(outputFile, ".") + "." + KEY_FILE_EXTENSION; FileOutputStream os = new FileOutputStream(tmpFileName); os.write(key); os.close(); // Initiate ZipFile object with the path/name of the zip file. ZipFile zipFile = new ZipFile(outputFile); // Initiate Zip Parameters which define various properties such // as compression method, etc. More parameters are explained in other // examples ZipParameters parameters = new ZipParameters(); parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // set compression method to store compression // Set the compression level. This value has to be in between 0 to 9 // Several predefined compression levels are available // DEFLATE_LEVEL_FASTEST - Lowest compression level but higher speed of compression // DEFLATE_LEVEL_FAST - Low compression level but higher speed of compression // DEFLATE_LEVEL_NORMAL - Optimal balance between compression level/speed // DEFLATE_LEVEL_MAXIMUM - High compression level with a compromise of speed // DEFLATE_LEVEL_ULTRA - Highest compression level but low speed parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); // Set the encryption flag to true // If this is set to false, then the rest of encryption properties are ignored parameters.setEncryptFiles(true); // Set the encryption method to AES Zip Encryption parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES); // Set AES Key strength. Key strengths available for AES encryption are: // AES_STRENGTH_128 - For both encryption and decryption // AES_STRENGTH_192 - For decryption only // AES_STRENGTH_256 - For both encryption and decryption // Key strength 192 cannot be used for encryption. But if a zip file already has a // file encrypted with key strength of 192, then Zip4j can decrypt this file parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256); // Set password parameters.setPassword(password); // Now add files to the zip file // Note: To add a single file, the method addFile can be used // Note: If the zip file already exists and if this zip file is a split file // then this method throws an exception as Zip Format Specification does not // allow updating split zip files zipFile.addFile(new File(tmpFileName), parameters); // delete the key file FileUtils.deleteTempFile(tmpFileName); }//saveKey }