Documentation
General
Verify your license
The SDK contains a simple batch/shell script print_version
which will tell you if your library file is licensed or trial.
Javadoc/APIDOC
You can browse the API documentation here: CrococryptLib Online APIDOC.
You can download the API documentation with the SDK for offline browsing.
Articles
We started to write how-to articles on specific topics and will continue to so - enabling more people to write crypto-related code for applications:
- No to plain passwords: Secure Password Hashing
- Encryption background: What is key wrapping?
- Password-based Encryption made easy
Examples
The following examples from the SDK include demos and typical use cases that can also be used as a pattern for own applications.
Example file | Description |
---|---|
SimplePBEEncryptionExample.java | Simplest way of securely encrypting a message or binary code with a password |
CompactEncryptionExamples.java | Symmetric encryption with a raw key, auto-generation and storing of all encryption parameters |
PasswordBasedKeyExample.java | Persist the parameters of a key which was securely derived from a password |
SimplePasswordHashExample.java | If you do not need encryption, this example demonstrates how to easily store a secure password hash instead of plain passwords in your application |
SimplePBEFileEncryptionExample.java | Using the efficient compact stream format, this example demonstrates a very simple but secure password-based file encryption tool |
SimplePBEFileEncryptionExampleShort.java | The same example but without comments |
PBEFileEncryption_CustomSettings.java | All default crypto settings can be changed - for performance or flavor reasons |
PasswordHash_WithCustomSettings.java | Secure hashing with custom settings |
PasswordKeyWrapping_PlusPasswordChange.java | A full example of key encryption. That means, every user gets an encryption key which is securely wrapped using a key encryption key based on the user's password. |
AndroidSetupExample.java | Example of an Android app's Activity |
Simple Examples
There is no further crypto knowledge required to use these patterns in your software.
SimplePBEEncryptionExample
Uses the following defaults: PBKDF2 key derivation with a SHA512 HMAC, 100000 iterations, 512 Bit salt and AES-256 in CBC mode.
public class SimplePBEEncryptionExample {
public static void main(String[] args) throws Exception{
String password = "Demo Password!";
String textToencrypt = "Secret text to be encrypted, could also be any binary data";
CompactPasswordKey key = CompactPasswordKey.generateKey(new Secret(password));
String encryptedMessage = new CompactEncryption(key).encryptToBase64(new StringData(textToencrypt));
System.out.println("\nEncrypted message: " + encryptedMessage);
System.out.println("\nDecrypted message: " + new CompactEncryption(key).decryptFromBase64(encryptedMessage));
}
}
Creates this output:
Encrypted message: AAAAAAIAAAAQ1SHBVLPfXMbOOV7rvSnrcgAAAGBwEOiB9h3H-KtVW1-1XPFi7H2dm61_0-DWaiCUafgzFuUaelB46X1pmijNCWd92BkqLlJ0F2NLbzFFGYvJGJgVztFf49WnAJ_J8B0OXLWgYuLkPdygH57CAHTnhSN9pP8
Decrypted message: Secret text to be encrypted, could also be any binary data
You will not be able to reproduce the same output since: a) every new CompactPasswordKey
will have a new salt and b) every call of one of the CompactEncryption.encrypt*
methods automatically creates a new IV.
CompactEncryptionExamples
public class CompactEncryptionExamples {
public static void main(String[] args) {
//Securely generate a raw symmetric key (e.g., for AES-256)
EncryptionKey key = EncryptionKey.generateNewKey();
System.out.println("Default keylength: " + key.getKeyInBytes().length);
System.out.println("Base64 encoded format: " + key.writeToBase64());
System.out.println("Default encryption: " + new CompactEncryption(key).getAlgorithm());
System.out.println();
String message = "Plain message. Could also be binary.";
//The encryption includes all necessary parameters,
//including a securely generated IV for the CBC block cipher mode
String encryptedMessage = new CompactEncryption(key).encryptToBase64(new StringData(message));
System.out.println("Encrypted message: " + encryptedMessage);
System.out.println("Decrypted message: " + ((StringData)new CompactEncryption(key)
.decryptFromBase64(encryptedMessage)).getDataString());
System.out.println();
//Every symmetric block cipher available in the JCE can be used
String encryptedMessage2 = new CompactEncryption(key, "Blowfish").encryptToBase64(new StringData(message));
System.out.println("Encrypted message: " + encryptedMessage2);
System.out.println("Decrypted message: " + ((StringData)new CompactEncryption(key)
.decryptFromBase64(encryptedMessage2)).getDataString());
}
}
PasswordBasedKeyExample
public class PasswordBasedKeyExample {
public static void main(String[] args) {
//Provide a password via commandline or use the demo password instead
if(args == null || args.length == 0 || args[0] == null)
args = new String[]{"Demo Password!"};
//Creating a PBKDF2 based key derivation
CompactPasswordKey key = CompactPasswordKey.generateKey(new Secret(args[0]));
//Store the compact key derivation format in various output formats. This includes the all
//necessary parameters (algorithm, salt, iteration count) plus an encryption checksum that
//tell's us if the password is correct
System.out.println("Hash (Hex): " + key.writeToHex());
System.out.println("Hash (B64): " + key.writeToBase64());
byte[] binaryObject = key.writeToBytes();
//Let's assume 'binaryObject' had been written to a database and was being reloaded.
CompactPasswordKey theKey = CompactPasswordKey.newInstance(new Secret(args[0]));
theKey.readFromBytes(binaryObject);
//Perform a validation check of the newly provided password
System.out.println(theKey.isPasswordValid());
//Perform a validation check that has to fail
theKey = CompactPasswordKey.newInstance(new Secret("wrong password"));
theKey.readFromBytes(binaryObject);
System.out.println(theKey.isPasswordValid());
}
}
SimplePasswordHashExample
public class SimplePasswordHashExample {
public static void main(String[] args) {
//Provide a password via commandline or use the demo password instead
if(args == null || args.length == 0 || args[0] == null)
args = new String[]{"Demo Password!"};
//Creating a PBKDF2 based secure password hash with default settings
CompactPasswordHash cph = CompactPasswordHash.generateHash(new Secret(args[0]));
//Store the compact hash format in various output formats. This includes the complete hash including
//all necessary parameters (algorithm, salt, iteration count).
System.out.println("Hash (Hex): " + cph.writeToHex());
System.out.println("Hash (B64): " + cph.writeToBase64());
byte[] raw = cph.writeToBytes();
//Let's assume 'raw' had been written to a database and was being reloaded.
CompactPasswordHash cph_loaded = CompactPasswordHash.newInstance();
cph_loaded.readFromBytes(raw);
//Perform a validation check of the newly provided password against the stored hash
System.out.println(cph_loaded.verifyPassword(new Secret(args[0])));
//Perform a validation check that has to fail
System.out.println(cph_loaded.verifyPassword(new Secret("wrongPassword")));
}
}
SimplePBEFileEncryptionExample
public class SimplePBEFileEncryptionExample {
public static void main(String[] args) throws Exception{
String password = "Demo Password!";
//Creating a PBKDF2 based key derivation
//DEFAULTS:
//+ HmacSHA512
//+ 100000 iterations
//+ AES-256
//+ 256bit keylength
//+ 512bit salt
CompactPasswordKey key = CompactPasswordKey.generateKey(new Secret(password));
//Creating a temp file for demonstration with some content, initializing the streams
File inputFile = createDemoFile();
File outputFile = File.createTempFile("crococryptlibdemo-ENCRYPTEDFILE-", ".data");
FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile);
//Writing the PBE/PBKDF2 parameters to the file
key.writeToStream(fos);
//ENCRYPTION
//DEFAULTS:
//+ AES-256
//+ 256bit keylength
//+ CBC mode
//+ 16byte initialization vector (IV)
//NOTE: This class can utilize any stream, a file stream is just an example!
CompactBinarystreamEncryption cbe = new CompactBinarystreamEncryption(key);
cbe.encrypt(fis, fos);
fis.close();
fos.close();
//---ENCRYPTION DONE---
System.out.println("Written from " + inputFile + " to " + outputFile);
//DECRYPTION
File tmp = outputFile;
outputFile = File.createTempFile("crococryptlibdemo-DECRYPTEDFILE-", ".txt");
inputFile = tmp;
fis = new FileInputStream(inputFile);
fos = new FileOutputStream(outputFile);
//Reading the PBE/PBKDF2 from the stream
key = CompactPasswordKey.newInstance(new Secret(password));
key.readFromStream(fis);
//Actual decryption
cbe = new CompactBinarystreamEncryption(key);
cbe.decrypt(fis, fos);
fis.close();
fos.close();
System.out.println("Written from " + inputFile + " to " + outputFile);
//---DECRYPTION DONE---
}
private static final File createDemoFile() throws Exception{
File tmp = File.createTempFile("crococryptlibdemo-ORIGINALFILE-", ".txt");
FileOutputStream fos = new FileOutputStream(tmp);
fos.write("Small demo file".getBytes());
fos.flush();
fos.close();
return tmp;
}
}
SimplePBEFileEncryptionExampleShort
public class SimplePBEFileEncryptionExampleShort {
public static void main(String[] args) throws Exception{
String password = "Demo Password!";
FileInputStream fis = new FileInputStream(createDemoFile());
File outputFile = File.createTempFile("crococryptlibdemo-ENCRYPTEDFILE-", ".data");
FileOutputStream fos = new FileOutputStream(outputFile);
CompactPasswordKey key = CompactPasswordKey.generateKey(new Secret(password));
key.writeToStream(fos);
new CompactBinarystreamEncryption(key).encrypt(fis, fos);
fis.close();
fos.close();
System.out.println("Encryption finished successfully: " + outputFile.getAbsolutePath());
fis = new FileInputStream(outputFile);
fos = new FileOutputStream(File.createTempFile("crococryptlibdemo-DECRYPTEDFILE-", ".txt"));
key = CompactPasswordKey.newInstance(new Secret(password));
key.readFromStream(fis);
new CompactBinarystreamEncryption(key).decrypt(fis, fos);
fis.close();
fos.close();
System.out.println("Decryption finished successfully: " + outputFile.getParent());
}
private static final File createDemoFile() throws Exception{
File tmp = File.createTempFile("crococryptlibdemo-ORIGINALFILE-", ".txt");
FileOutputStream fos = new FileOutputStream(tmp);
fos.write("Small demo file".getBytes());
fos.flush();
fos.close();
return tmp;
}
}
Complex Examples
You can change all crypto parameters. However, you should know what you are doing when you go that route since weak algorithms or operation parameters can weaken the security of your application's data.
PBEFileEncryption_CustomSettings
public class PBEFileEncryption_CustomSettings {
public static void main(String[] args) throws Exception{
String password = "Demo Password!";
//Creating a PBKDF2 based key derivation
//Every single parameter can be changed or let to default
GenerationParametersCPK parameters = CompactPasswordKey.createParameters();
parameters.hmacAlgorithm = "HmacWhirlpool";
parameters.iterationCount = 10000;
parameters.keyLengthInBytes = 24;
parameters.saltLengthInBytes = 20;
parameters.checksumEncryptionAlgorithm = "Twofish";
CompactPasswordKey key = CompactPasswordKey.generateKey(new Secret(password), parameters);
//Creating a temp file for demonstration with some content, initializing the streams
File inputFile = createDemoFile();
File outputFile = File.createTempFile("crococryptlibdemo-ENCRYPTEDFILE-", ".data");
FileInputStream fis = new FileInputStream(inputFile);
FileOutputStream fos = new FileOutputStream(outputFile);
//Writing the PBE/PBKDF2 parameters to the file
key.writeToStream(fos);
//ENCRYPTION
//Using CBC mode (standard) with Twofish instead of AES. Keylength will be 192bit (see above)
CompactBinarystreamEncryption cbe = new CompactBinarystreamEncryption(key, "Twofish");
cbe.encrypt(fis, fos);
fis.close();
fos.close();
System.out.println("Written from " + inputFile + " to " + outputFile);
//DECRYPTION
File tmp = outputFile;
outputFile = File.createTempFile("crococryptlibdemo-DECRYPTEDFILE-", ".txt");
inputFile = tmp;
fis = new FileInputStream(inputFile);
fos = new FileOutputStream(outputFile);
//Reading the PBE/PBKDF2 from the stream
key = CompactPasswordKey.newInstance(new Secret(password));
key.readFromStream(fis);
//Actual decryption
cbe = new CompactBinarystreamEncryption(key);
cbe.decrypt(fis, fos);
fis.close();
fos.close();
System.out.println("Written from " + inputFile + " to " + outputFile);
}
private static final File createDemoFile() throws Exception{
File tmp = File.createTempFile("crococryptlibdemo-ORIGINALFILE-", ".txt");
FileOutputStream fos = new FileOutputStream(tmp);
fos.write("Small demo file".getBytes());
fos.flush();
fos.close();
return tmp;
}
}
PasswordHash_WithCustomSettings
public class PasswordHash_WithCustomSettings {
public static void main(String[] args) {
//Provide a password via commandline or use the demo password instead
if(args == null || args.length == 0 || args[0] == null)
args = new String[]{"Demo Password!"};
//Creating a PBKDF2 based secure password hash with custom settings
GenerationParametersCPH parameters = CompactPasswordHash.createParameters();
parameters.hmacAlgorithm = "HmacWhirlpool";
parameters.hashLengthInBytes = 16;
parameters.iterationCount = 5000;
CompactPasswordHash compactHash = CompactPasswordHash.generateHash(new Secret(args[0]), parameters);
//Store the compact hash format in various output formats. This includes the complete hash including
//all necessary parameters (algorithm, salt, iteration count).
System.out.println("\nHash (Hex): " + compactHash.writeToHex());
System.out.println("\nHash (B64): " + compactHash.writeToBase64());
byte[] raw = compactHash.writeToBytes();
//Let's assume 'raw' had been written to a database and was being reloaded.
CompactPasswordHash theHash = CompactPasswordHash.newInstance();
theHash.readFromBytes(raw);
//Perform a validation check of the newly provided password against the stored hash
System.out.println(theHash.verifyPassword(new Secret(args[0])));
//Perform a validation check that has to fail
System.out.println(theHash.verifyPassword(new Secret("wrongPassword")));
}
}
PasswordKeyWrapping_PlusPasswordChange
public class PasswordKeyWrapping_PlusPasswordChange {
public static void main(String[] args) {
String password = "password";
Secret secret = new Secret(password);
//---ENCRYPTION AND KEYWRAPPING---
//Securely generate a new default 256bit key, e.g., for AES
EncryptionKey encKey = EncryptionKey.generateNewKey();
//Create a password-based key, e.g., for an application user
CompactPasswordKey pwKey = CompactPasswordKey.generateKey(secret);
WrapUtil wrapper = new WrapUtil(pwKey);
byte[] pwKey_atStorage = pwKey.writeToBytes();
byte[] wrappedEncKey_atStorage = wrapper.wrapToBytes(encKey);
String message = "A text message, file, binary or stream";
String encryptedMessage = new CompactEncryption(encKey).encryptToBase64(new StringData(message));
//---DECRYPTION---
//Load the key material
pwKey = CompactPasswordKey.newInstance(secret).readFromBytes(pwKey_atStorage);
wrapper = new WrapUtil(pwKey);
encKey = wrapper.unwrapFromBytes(wrappedEncKey_atStorage);
//Perform the decryption
System.out.println("Decrypted message: " +
new CompactEncryption(encKey).decryptFromBase64(encryptedMessage));
//---REWRAPPING A KEY FOR A PASSWORD CHANGE (old and new password required)---
String newPassword = "new password";
CompactPasswordKey newPwKey = CompactPasswordKey.generateKey(new Secret(newPassword));
//Note: The actual encryption key remains the same, although the password was changed.
// Hence, all encrypted data can still be decrypted! This is why there is the actual
// encryption key and a key encryption key (in this case password-based).
wrappedEncKey_atStorage = wrapper.rewrapFromBytes(wrappedEncKey_atStorage, newPwKey);
pwKey_atStorage = newPwKey.writeToBytes();
//---RETRY THE DECRYPTION WITH THE REWRAPPED KEY FOR DEMONSTRATION ONLY---
encKey = new WrapUtil(newPwKey).unwrapFromBytes(wrappedEncKey_atStorage);
System.out.println("Decrypted message (new password): " +
new CompactEncryption(encKey).decryptFromBase64(encryptedMessage));
}
}
Android
Examples
AndroidSetupExample
This is one of the simple examples above that includes also the basic setup information for an Android activity:
public class AndroidSetupExample extends Activity {
static{
//Basic setup: Copy the croco.jar into your Android project's 'lib' folder,
//the bcprov.jar is NOT(!) required.
//This step is REQUIRED to enable Android mode
CryptoMain.setAndroidMode();
//The following code DOES NOT(!) apply for the pre-activated trial nor the licensed library!
//If you are running the online trial,
//you have to add the following permissions to your AndroidManifest.xml:
//<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
//<uses-permission android:name="android.permission.INTERNET" />
//The following lines are necessary for the online activation only:
/*
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
*/
}
/**
* This is a demo that can be used within an Android activity.
* It requires a simple TextView with the view ID 'text' for the output
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView) findViewById(R.id.text);
String password = "Demo Password!";
String textToencrypt = "Secret text to be encrypted, could also be any binary data";
CompactPasswordKey key = CompactPasswordKey.generateKey(new Secret(password));
String encryptedMessage = new CompactEncryption(key).encryptToBase64(new StringData(textToencrypt));
String tmp = ("\nEncrypted message:\n" + encryptedMessage);
tmp += ("\n\nDecrypted message:\n" + new CompactEncryption(key).decryptFromBase64(encryptedMessage));
tv.setText(tmp);
}
}