
Encryption and random number generation in Android applications. Test cases
In this article, we present test fragments of code that implements two security-critical functions in Android applications: random number generation and data encryption. We recommend that you try all the above options, and after reading the text, compile the test application by downloading it from the link.
There are two options for encrypting data for Android: using the Java Crypto API and the OpenSSL API (native code). We will look at both.

Now you can use the generated key to encrypt data files. To do this, we encrypt blocks of bytes using the AES algorithm using javax.crypto.
First, generate a key and iv.
Now we can use the generated key (cKeyBuffer) to encrypt the file. Initialize EVP with your key and iv. Now feed the byte blocks to the input of the EVP_EncryptUpdate function. The last portion of bytes from your file should be fed to the EVP_EncryptFinal_ex function.
Original article on the Intel IDZ website Samples of the
test application

There are as many as 4 ways to generate random numbers in Android:
However, if you use RNG to generate a key that protects your data, using the regular Random class is not recommended, as it is easiest to crack. The remaining 3 methods provide more reliable protection.
Original article on the Intel IDZ website Samples of the
test application
Data encryption
Encryption is important because it allows you to hide from prying eyes that they should not see. Mobile devices are storing more and more significant information, and protecting it is the direct responsibility of every developer.There are two options for encrypting data for Android: using the Java Crypto API and the OpenSSL API (native code). We will look at both.

Java Crypto API
Using the Java Crypto API for Android is very simple. First you need to generate an encryption key. The KeyGenerator class in the javax.crypto package is responsible for this.mKey = null;
try {
kgen = KeyGenerator.getInstance("AES");
mKey = kgen.generateKey();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
Now you can use the generated key to encrypt data files. To do this, we encrypt blocks of bytes using the AES algorithm using javax.crypto.
// open stream to read origFilepath. We are going to save encrypted contents to outfile
InputStream fis = new FileInputStream(origFilepath);
File outfile = new File(encFilepath);
int read = 0;
if (!outfile.exists())
outfile.createNewFile();
FileOutputStream encfos = new FileOutputStream(outfile);
// Create Cipher using "AES" provider
Cipher encipher = Cipher.getInstance("AES");
encipher.init(Cipher.ENCRYPT_MODE, mKey);
CipherOutputStream cos = new CipherOutputStream(encfos, encipher);
// capture time it takes to encrypt file
start = System.nanoTime();
Log.d(TAG, String.valueOf(start));
byte[] block = new byte[mBlocksize];
while ((read = fis.read(block,0,mBlocksize)) != -1) {
cos.write(block,0, read);
}
cos.close();
stop = System.nanoTime();
Log.d(TAG, String.valueOf(stop));
seconds = (stop - start) / 1000000;// for milliseconds
Log.d(TAG, String.valueOf(seconds));
fis.close();
OpenSSL API
Encrypting data through OpenSSL for Android requires writing native C code, which is available in Java through JNI calls. This takes more time, but the performance will be higher as a result.First, generate a key and iv.
unsigned char cKeyBuffer[KEYSIZE/sizeof(unsigned char)];
unsigned char iv[] = "01234567890123456";
int opensslIsSeeded = 0;
if (!opensslIsSeeded) {
if (!RAND_load_file("/dev/urandom", seedbytes)) {
return -1;
}
opensslIsSeeded = 1;
}
if (!RAND_bytes((unsigned char *)cKeyBuffer, KEYSIZE )) {
}
Now we can use the generated key (cKeyBuffer) to encrypt the file. Initialize EVP with your key and iv. Now feed the byte blocks to the input of the EVP_EncryptUpdate function. The last portion of bytes from your file should be fed to the EVP_EncryptFinal_ex function.
if (!(EVP_EncryptInit_ex(e_ctx, EVP_aes_256_cbc(), NULL, cKeyBuffer, iv ))) {
ret = -1;
printf( "ERROR: EVP_ENCRYPTINIT_EXn");
}
// go through file, and encrypt
if ( orig_file != NULL ) {
origData = new unsigned char[aes_blocksize];
encData = new unsigned char[aes_blocksize+EVP_CIPHER_CTX_block_size(e_ctx)]; // potential for encryption to be 16 bytes longer than original
printf( "Encoding file: %sn", filename);
bytesread = fread(origData, 1, aes_blocksize, orig_file);
// read bytes from file, then send to cipher
while ( bytesread ) {
if (!(EVP_EncryptUpdate(e_ctx, encData, &len, origData, bytesread))) {
ret = -1;
printf( "ERROR: EVP_ENCRYPTUPDATEn");
}
encData_len = len;
fwrite(encData, 1, encData_len, enc_file );
// read more bytes
bytesread = fread(origData, 1, aes_blocksize, orig_file);
}
// last step encryption
if (!(EVP_EncryptFinal_ex(e_ctx, encData, &len))) {
ret = -1;
printf( "ERROR: EVP_ENCRYPTFINAL_EXn");
}
encData_len = len;
fwrite(encData, 1, encData_len, enc_file );
// free cipher
EVP_CIPHER_CTX_free(e_ctx);
Original article on the Intel IDZ website Samples of the
test application
Random number generation
A random number generator (RNG) is a program or device for producing a random sequence of numbers over a specific interval. RNG is vital to application security. In reality, the cryptographic protocol can be very reliable, but at the same time subject to a variety of attacks due to the fact that it basically uses weak key generation methods. To strengthen the key and increase the reliability of the entire system as a whole, RNG hardware support can be used.
There are as many as 4 ways to generate random numbers in Android:
- java.util.random
- java.security.SecureRandom
- / dev / urandom
- OpenSSL API
However, if you use RNG to generate a key that protects your data, using the regular Random class is not recommended, as it is easiest to crack. The remaining 3 methods provide more reliable protection.
java.util.random
Using the Java Random Number API is very simple. Calling Random.nextInt () will return a 4-byte random value (the total number of possible values is 2 32 ). This API is well suited for cases where you do not need to rely on truly random numbers.for (int i = 0; i < lastVal; i += 2) {
dataRandomPoints[i] = (rand.nextInt() % widget_width);
dataRandomPoints[i+1] = (rand.nextInt() % widget_height);
}
java.security.SecureRandom
SecureRandom is similar to java.util.Random in the sense that it also returns a 4-byte value. SecureRandom is cryptographically more reliable, however, developers should read the recent recommendation to generate a seed value using / dev / urandom for SecureRandom before generating random numbers. In the example below, / dev / urandom is not used.SecureRandom srand = new SecureRandom();
shouldDraw = (srand.nextInt() % randomMod );
/ dev / urandom
All Linux family operating systems, including Android, have a special file created by the kernel that can be used to provide random numbers to applications. Among all 4 methods, this is the slowest one, it generates cryptographically safe values with high entropy by combining noise quantities from various parts of the operating system (for example, device drivers) for RNG. We can get a random number directly from the kernel by reading the file / dev / urandom. / dev / urandom has access to the hardware RNG, if any.unsigned int cKeyBuffer[keysize];
memset(cKeyBuffer, 0, sizeof(unsigned int) * keysize);
FILE *fin;
strcpy(filein, "/dev/urandom");
fin = fopen(filein, "rb");
if (fin != NULL) {
fread(cKeyBuffer, sizeof(int), keysize, fin);
fclose (fin);
}
OpenSSL API
We can also use the OpenSSL API to get random numbers in native C code. In OpenSSL, you can use seed bytes from / dev / urandom to generate cryptographically secure random numbers. The OpenSSL API will access the hardware RNG, if any.int seedbytes = 1024;
unsigned int cKeyBuffer[keysize];
memset(cKeyBuffer, 0, sizeof(unsigned int) * keysize);
if (!opensslIsSeeded) {
if (!RAND_load_file("/dev/urandom", seedbytes)) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "Failed to seed OpenSSL RNG");
return jKeyBuffer;
}
opensslIsSeeded = 1;
}
if (!RAND_bytes((unsigned char *)cKeyBuffer, keysize * sizeof(int))) {
__android_log_print(ANDROID_LOG_ERROR, TAG, "Faled to create OpenSSSL random integers: %ul", ERR_get_error);
}
Original article on the Intel IDZ website Samples of the
test application