Hello,
Through several articles, I would like present the cryptographic mechanisms, types of keys, certificate, types of algorithms …etc:
- PRESENTATION : Concepts of Cryptography (concepts, types of keys symmetric/asymmetric, …)
- The principles of SSL
- The principles of Signature and Certificate
- The principles of Hardware Security Module HSM
- Encoding with base64, base64url, rfc-4648
- Encryption with Blowfish (Anonymization)
- Encryption with AES/CBC, AES/EBC (Encryption of files)
- Encryption with PBEWithMD5AndDES (Encryption of files)
- Encryption with RSA (asymmetric keys private and public)
- KeyStore, JCEKS, SecretKey, PrivateKey, PublicKey, Certificate
- Example, Use of SecretKey, PrivateKey, PublicKey, CSV file (CryptoTools, GenericObfuscationFile)
Encryption with PBEWithMD5AndDES (Encryption of files)
- 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.
- 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]
- 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 :01
private
static
final
String ALGORITHM =
"PBEWithMD5AndDES"
;
02
// Iteration count
03
private
static
final
int
ITERATION_COUNT =
20
;
04
private
static
final
String UNICODE_FORMAT =
"UTF-8"
;
05
06
public
static
byte
[] generateComplexPasswordOrSecretKeyValue()
throws
Exception {
07
byte
[] passwordOrKeyValue = RandomStringUtils.randomAscii(
16
).getBytes(UNICODE_FORMAT);
08
KeySpec keySpec =
new
PBEKeySpec(
new
String(passwordOrKeyValue).toCharArray());
09
SecretKey secretKey = SecretKeyFactory.getInstance(ALGORITHM).generateSecret(keySpec);
10
return
secretKey.getEncoded();
11
}
… Code for the SALT creation via Secure Random Number Generator and an empty 8byte array:
01
public
static
byte
[] generateSALT()
throws
Exception {
02
byte
[] saltValue =
null
;
03
//saltValue = { (byte) 0xc8, (byte) 0x73, (byte) 0x61, (byte) 0x1d, (byte) 0x1a, (byte) 0xf2, (byte) 0xa8, (byte) 0x99, };
04
//saltValue = "HOJAvaLu".getBytes(UNICODE_FORMAT);
05
{
06
SecureRandom r =
new
SecureRandom();
07
byte
[] newSeed = r.generateSeed(
8
);
08
r.setSeed(newSeed);
09
saltValue =
new
byte
[
8
];
10
r.nextBytes(saltValue);
11
}
12
return
saltValue;
13
}
… Encryption/ciphering code :
01
char
[] passwordOrKeyValue = ....;
02
byte
[] content = ....;
03
byte
[] salt = ....;
04
05
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
06
07
// Create PBE parameter set with SALT and COUNTER
08
PBEParameterSpec pbeParamSpec =
new
PBEParameterSpec(salt, ITERATION_COUNT);
09
10
// Create SecretKey
11
PBEKeySpec pbeKeySpec =
new
PBEKeySpec(passwordOrKeyValue);
12
SecretKey key = keyFactory.generateSecret(pbeKeySpec);
13
14
// Create PBE Cipher
15
Cipher pbeCipher = Cipher.getInstance(ALGORITHM);
16
17
// Initialize PBE Cipher with key, PBE parameter set
18
pbeCipher.init(Cipher.ENCRYPT_MODE, key, pbeParamSpec);
19
20
byte
[] encryptedContent = pbeCipher.doFinal(content);
21
return
base64Encode(encryptedContent).getBytes(UNICODE_FORMAT);
… Decryption/deciphering code :
01
02
char
[] passwordOrKeyValue = ....;
03
byte
[] content = ....;
04
byte
[] salt = ....;
05
06
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
07
08
// Create PBE parameter set with SALT and COUNTER
09
PBEParameterSpec pbeParamSpec =
new
PBEParameterSpec(salt, ITERATION_COUNT);
10
11
// Create SecretKey
12
PBEKeySpec pbeKeySpec =
new
PBEKeySpec(passwordOrKeyValue);
13
SecretKey key = keyFactory.generateSecret(pbeKeySpec);
14
15
// Create PBE Cipher
16
Cipher pbeCipher = Cipher.getInstance(ALGORITHM);
17
18
// Initialize PBE Cipher with key, PBE parameter set
19
pbeCipher.init(Cipher.DECRYPT_MODE, key, pbeParamSpec);
20
return
pbeCipher.doFinal(base64Decode(
new
String(content)));
…here the main method with PBEWithMD5AndDES encryption and Base64 encoding:
01
public
static
void
main(String[] args) {
02
try
{
03
byte
[] passwordOrKeyValue = EncryptionPBEWithMD5AndDES.generateComplexPasswordOrSecretKeyValue();
04
System.out.println(
"Generation of complex password : "
+
new
String(passwordOrKeyValue));
05
byte
[] salt = EncryptionPBEWithMD5AndDES.generateSALT();
06
System.out.println(
"SALT used: "
+
new
String(salt));
07
aEncryptFile(passwordOrKeyValue, salt);
08
bDecryptFile(passwordOrKeyValue, salt);
09
}
catch
(Throwable th){
10
th.printStackTrace();
11
}
12
}
13
14
public
static
void
aEncryptFile(
byte
[] keyValue,
byte
[] salt)
throws
Exception {
15
try
{
16
File sourceFile =
new
File(System.getProperty(
"user.dir"
) +
"/resources/pdf_with_text.pdf"
);
17
System.out.println(
"Size of source file (to encrypt): "
+ sourceFile.length());
18
19
byte
[] content = Files.readAllBytes(sourceFile.toPath());
20
//
21
byte
[] encryptContent = EncryptionPBEWithMD5AndDES.encrypt(
new
String(keyValue).toCharArray(), content, salt);
22
//
23
File targetFile =
new
File(System.getProperty(
"user.dir"
) +
"/resources/pdf_with_text_encrypted_pbe.pdf"
);
24
if
(targetFile.exists()){
25
targetFile.delete();
26
}
27
Files.write(targetFile.toPath(), encryptContent, StandardOpenOption.CREATE_NEW);
28
29
System.out.println(
"Size of encrypted file : "
+ targetFile.length());
30
}
catch
(Exception e){
31
e.printStackTrace();
32
}
33
}
34
35
public
static
void
bDecryptFile(
byte
[] keyValue,
byte
[] salt)
throws
Exception {
36
try
{
37
byte
[] encryptContent = Files.readAllBytes(
new
File(System.getProperty(
"user.dir"
) +
"/resources/pdf_with_text_encrypted_pbe.pdf"
).toPath());
38
System.out.println(
"Size of encrypted file (to decrypt): "
+ encryptContent.length);
39
40
byte
[] decryptContent = EncryptionPBEWithMD5AndDES.decrypt(
new
String(keyValue).toCharArray(), encryptContent, salt);
41
File targetFile =
new
File(System.getProperty(
"user.dir"
) +
"/resources/pdf_with_text_decrypted_pbe.pdf"
);
42
if
(targetFile.exists()){
43
targetFile.delete();
44
}
45
Files.write(targetFile.toPath(), decryptContent, StandardOpenOption.CREATE_NEW);
46
47
System.out.println(
"Size of decrypted file : "
+ targetFile.length());
48
}
catch
(Exception e){
49
e.printStackTrace();
50
}
51
}
…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