Hello,
Through several articles, I would like present the cryptographic mechanisms, types of keys, certificate, types of algorithms …etc:

 


Encryption with PBEWithMD5AndDES (Encryption of files)
 

  1. Presentation
    The algorithms PBEWith are password based encryption. To perform password-based encryption, a random salt sequence in order to prevent dictionary attacks, and key (AES or DES) generated from a given password and salt are necessary.

    There are several possible variations, but a common scheme is as follows:

    • append the password to the salt, and also append a counter, which will start at 1 in order to create a complex sequence;
    • calculate a secure hash of the previous created;
    • then repeat the process for some number of iterations, each time forming the new sequence to be hashed from the output of the previous hash, and appending the salt and incremented counter.


    The PBEWithMD5AndDES combines all the benefits of slow, insecure 56-bit encryption (DES-CBC) with an insecure hash function (MD5).
    However, there are others algorithms: PBEWithSHA1AndRC2_40, PBEWithMD5AndTripleDES …etc.
     

  2. Tools
    As described in the post http://www.javablog.fr/javacrypto-encryption-list-providers-and-algo.html, we could find the available algorithm, tools (cipher, generator) in each reachable provider. In our case, we use the SunJCE Provider which is enough (http://javasearch.developpez.com/sun/j2se/1.6.0/technotes/guides/security/SunProviders.html#SunJCEProvider)
    The following algorithms are available in the SunJCE provider:

    [4] SunJCE v1.6: SunJCE Provider (implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, Diffie-Hellman, HMAC)
    - AlgorithmParameters.PBEWithMD5AndDES -> com.sun.crypto.provider.PBEParameters
    aliases: [OID.1.2.840.113549.1.5.3, 1.2.840.113549.1.5.3]
    - Cipher.PBEWithMD5AndDES -> com.sun.crypto.provider.PBEWithMD5AndDESCipher
    aliases: [OID.1.2.840.113549.1.5.3, 1.2.840.113549.1.5.3]
    - SecretKeyFactory.PBEWithMD5AndDES -> com.sun.crypto.provider.PBEKeyFactory$PBEWithMD5AndDES
    aliases: [OID.1.2.840.113549.1.5.3, 1.2.840.113549.1.5.3, PBE]

     
  3. Example : Encryption of data/file via the algorithme “PBEWithMD5AndDES”
    Details:
    * Encryption : PBEWithMD5AndDES AND [Base64 and replacing of ‘+’ by ‘-‘, ‘/’ by ‘_’ and removing the ‘=’ at the end]
    * Decryption : [Base64 and replacing of ‘-‘ by ‘+’, ‘_’ by ‘/’ and adding at the end a ‘=’] AND PBEWithMD5AndDES

    … Code for the generation of Complex Password due to Secret Key Value :

        private static final String ALGORITHM = "PBEWithMD5AndDES";
        // Iteration count
        private static final int ITERATION_COUNT = 20;
        private static final String UNICODE_FORMAT  = "UTF-8";
    
        public static byte[] generateComplexPasswordOrSecretKeyValue() throws Exception {
        	byte[] passwordOrKeyValue = RandomStringUtils.randomAscii(16).getBytes(UNICODE_FORMAT);
        	KeySpec keySpec = new PBEKeySpec(new String(passwordOrKeyValue).toCharArray());
            SecretKey secretKey = SecretKeyFactory.getInstance(ALGORITHM).generateSecret(keySpec);
            return secretKey.getEncoded();
        }
    

    … Code for the SALT creation via Secure Random Number Generator and an empty 8byte array:

        public static byte[] generateSALT() throws Exception {
        	byte[] saltValue = null;
        	//saltValue = { (byte) 0xc8, (byte) 0x73, (byte) 0x61, (byte) 0x1d, (byte) 0x1a, (byte) 0xf2, (byte) 0xa8, (byte) 0x99,  };    	
        	//saltValue = "HOJAvaLu".getBytes(UNICODE_FORMAT);
        	{
        		SecureRandom r = new SecureRandom();
            	byte[] newSeed = r.generateSeed(8);
            	r.setSeed(newSeed);
            	saltValue = new byte[8];
            	r.nextBytes(saltValue);
        	}
        	return saltValue;
        }
    

    … Encryption/ciphering code :

    char[] passwordOrKeyValue = ....; 
    byte[] content = ....; 
    byte[] salt = ....;
    
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
           
    // Create PBE parameter set with SALT and COUNTER
    PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
            		
    // Create SecretKey
    PBEKeySpec pbeKeySpec = new PBEKeySpec(passwordOrKeyValue);
    SecretKey key = keyFactory.generateSecret(pbeKeySpec);
    
    // Create PBE Cipher
    Cipher pbeCipher = Cipher.getInstance(ALGORITHM);
            
    // Initialize PBE Cipher with key, PBE parameter set
    pbeCipher.init(Cipher.ENCRYPT_MODE, key, pbeParamSpec);
            
    byte[] encryptedContent = pbeCipher.doFinal(content);
    return base64Encode(encryptedContent).getBytes(UNICODE_FORMAT);
    

    … Decryption/deciphering code :

    	
    char[] passwordOrKeyValue = ....; 
    byte[] content = ....; 
    byte[] salt = ....;
    
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
    
    // Create PBE parameter set with SALT and COUNTER
    PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
    
    // Create SecretKey
    PBEKeySpec pbeKeySpec = new PBEKeySpec(passwordOrKeyValue);
    SecretKey key = keyFactory.generateSecret(pbeKeySpec);
            
    // Create PBE Cipher
    Cipher pbeCipher = Cipher.getInstance(ALGORITHM);
            
    // Initialize PBE Cipher with key, PBE parameter set
    pbeCipher.init(Cipher.DECRYPT_MODE, key, pbeParamSpec);
    return pbeCipher.doFinal(base64Decode(new String(content)));
    

    …here the main method with PBEWithMD5AndDES encryption and Base64 encoding:

    	public static void main(String[] args) {
    		try{
    			byte[] passwordOrKeyValue = EncryptionPBEWithMD5AndDES.generateComplexPasswordOrSecretKeyValue();
    			System.out.println("Generation of complex password : "+new String(passwordOrKeyValue));
    			byte[] salt = EncryptionPBEWithMD5AndDES.generateSALT();
    			System.out.println("SALT used: "+new String(salt));
    			aEncryptFile(passwordOrKeyValue, salt);
    			bDecryptFile(passwordOrKeyValue, salt);
    		}catch(Throwable th){
    			th.printStackTrace();
    		}
        }
    	
        public static void aEncryptFile(byte[] keyValue, byte[] salt) throws Exception {
            try{
                File sourceFile = new File(System.getProperty("user.dir") + "/resources/pdf_with_text.pdf");
                System.out.println("Size of source file (to encrypt): " + sourceFile.length());
    
                byte[] content = Files.readAllBytes(sourceFile.toPath());
                //
                byte[] encryptContent = EncryptionPBEWithMD5AndDES.encrypt(new String(keyValue).toCharArray(), content, salt);
                //
                File targetFile = new File(System.getProperty("user.dir") + "/resources/pdf_with_text_encrypted_pbe.pdf");
                if(targetFile.exists()){
                	targetFile.delete();
                }
                Files.write(targetFile.toPath(), encryptContent, StandardOpenOption.CREATE_NEW);
    
                System.out.println("Size of encrypted file : " + targetFile.length());
            } catch(Exception e){
    			e.printStackTrace();
            }
        }
    
        public static void bDecryptFile(byte[] keyValue, byte[] salt) throws Exception {
            try {
                byte[] encryptContent = Files.readAllBytes(new File(System.getProperty("user.dir") + "/resources/pdf_with_text_encrypted_pbe.pdf").toPath());
                System.out.println("Size of encrypted file (to decrypt): " + encryptContent.length);
    
                byte[] decryptContent = EncryptionPBEWithMD5AndDES.decrypt(new String(keyValue).toCharArray(), encryptContent, salt);
                File targetFile = new File(System.getProperty("user.dir") + "/resources/pdf_with_text_decrypted_pbe.pdf");
                if(targetFile.exists()){
                	targetFile.delete();
                }
                Files.write(targetFile.toPath(), decryptContent, StandardOpenOption.CREATE_NEW);
                
                System.out.println("Size of decrypted file : " + targetFile.length());
            }catch (Exception e){
    			e.printStackTrace();
            }
        }
    
    

     
    …here the outputs:
    Generation of complex password : %/%\eTx{}E,SG)l:
    SALT used: 5vëE“Î
    Size of source file (to encrypt): 882
    Size of encrypted file : 1214
    Size of encrypted file (to decrypt): 1214
    Size of decrypted file : 882

Note: the source file “/resources/pdf_with_text.pdf” and the file resulting of encryption/decryption “/resources/pdf_with_text_decrypted_pbe.pdf” are equals.

Sources : PBEWithMD5AndDES.zip

That’s all!!!

Huseyin OZVEREN