How to Implement Common Encryption Algorithms (MD5, SHA, DES, AES, RSA) in Android
This tutorial explains why learning encryption algorithms is essential for Android reverse engineering, distinguishes standard and non‑standard algorithms, and provides complete Java code examples for Hex/Base64 encoding, message‑digest (MD5, SHA‑1, MAC), symmetric ciphers (DES, 3DES, AES) and asymmetric RSA, all runnable in an Android Studio project.
Why Learn Encryption Algorithms
When reverse engineering, you often encounter hash strings such as 81dc9bdb52d04dc20036dbd8313ed055; understanding how they are generated requires knowledge of encryption algorithms.
Standard vs Non‑Standard Encryption Algorithms
Standard algorithms produce identical results across languages, while non‑standard algorithms are custom implementations that may vary.
Standard Encryption Algorithms
Standard encryption algorithms
Non‑standard encryption algorithms
In Android reverse engineering, standard algorithms in the Java layer have fixed names, making them easier to handle, whereas the C++ layer lacks fixed names and must be identified by characteristics.
Common Standard Algorithms
Message digest algorithms (MD5, SHA, MAC)
Symmetric encryption algorithms (DES, 3DES, AES)
Asymmetric encryption algorithm (RSA)
Digital signature algorithms (MD5withRSA, SHA1withRSA, SHA256withRSA)
We will reproduce these using Android.
My Environment
AndroidStudio 2020.3.1
Jdk 8Project
CryptologyDemo.zip
Hex and Base64
Hex and Base64 are encoding methods, not encryption, but they are the most common ways to represent encrypted data.
Adding Dependency
api 'com.squareup.okhttp3:okhttp:3.10.0'Remember to click Sync Now.
Hex
Hex encoding uses 16 characters (0‑9, a‑f) to represent arbitrary binary data.
Code
// from string to hex
byte[] bytes = "zhangsan".getBytes(StandardCharsets.UTF_8);
ByteString of = ByteString.of(bytes);
String hex = of.hex();
Log.d(TAG, "hex:" + hex);Base64
Base64 encoding uses 64 characters (A‑Z, a‑z, 0‑9, +, /, =) to represent binary data.
Code
// from string to base64
byte[] bytes = "zhangsan".getBytes(StandardCharsets.UTF_8);
ByteString of = ByteString.of(bytes);
// method 1
String base64 = of.base64();
Log.d(TAG, "base64_1:" + base64);
// method 2
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
String s = Base64.getEncoder().encodeToString("zhangsan".getBytes(StandardCharsets.UTF_8));
byte[] encode = Base64.getEncoder().encode("zhangsan".getBytes(StandardCharsets.UTF_8));
Log.d(TAG, "base64_2:" + s);
Log.d(TAG, "base64_2:" + new String(encode));
}
// method 3
String s = android.util.Base64.encodeToString("zhangsan".getBytes(StandardCharsets.UTF_8), 0);
Log.d(TAG, "base64_3:" + new String(s));Message Digest Algorithms
Message digest algorithms generate irreversible fixed‑length outputs.
Variable‑length input yields fixed‑length output.
The result is unique for each distinct input.
MD5
MD5 processes data via update and digest, typically displayed in hex.
Code
public static String md5(String plainText) throws Exception {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(plainText.getBytes(StandardCharsets.UTF_8));
byte[] digest = md5.digest();
ByteString of = ByteString.of(digest);
String hex = of.hex();
String base64 = of.base64();
return hex + "||" + base64;
}SHA‑1
SHA‑1 works similarly; only the algorithm name changes.
Code
public static String sha_1(String plainText) throws Exception {
MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
sha1.update(plainText.getBytes(StandardCharsets.UTF_8));
byte[] digest = sha1.digest();
ByteString of = ByteString.of(digest);
String hex = of.hex();
String base64 = of.base64();
return hex + "||" + base64;
}MAC
MAC adds a secret key to the hash, providing authentication.
Code
public static String mac(String plainText) throws Exception {
SecretKeySpec hmacMD5 = new SecretKeySpec("123".getBytes(StandardCharsets.UTF_8), "HmacMD5");
Mac instance = Mac.getInstance(hmacMD5.getAlgorithm());
instance.init(hmacMD5);
instance.update(plainText.getBytes(StandardCharsets.UTF_8));
byte[] doFinal = instance.doFinal();
ByteString of = ByteString.of(doFinal);
String hex = of.hex();
String base64 = of.base64();
return hex + "||" + base64;
}Symmetric Encryption Algorithms
Symmetric algorithms use the same key for encryption and decryption.
DES
ECB Mode Code
public static String des_encrypt_ECB(String plainText) throws Exception {
SecretKeySpec desKey = new SecretKeySpec("12345678".getBytes(StandardCharsets.UTF_8), "DES");
Cipher instance = Cipher.getInstance("DES/ECB/PKCS5Padding");
instance.init(Cipher.ENCRYPT_MODE, desKey);
byte[] doFinal = instance.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
ByteString of = ByteString.of(doFinal);
String hex = of.hex();
String base64 = of.base64();
return hex + "||" + base64;
}
public static String des_decrypt_ECB(byte[] cipherBytes) throws Exception {
SecretKeySpec desKey = new SecretKeySpec("12345678".getBytes(StandardCharsets.UTF_8), "DES");
Cipher instance = Cipher.getInstance("DES/ECB/PKCS5Padding");
instance.init(Cipher.DECRYPT_MODE, desKey);
byte[] doFinal = instance.doFinal(cipherBytes);
return new String(doFinal);
}CBC Mode Code
public static String des_encrypt_CBC(String plainText) throws Exception {
SecretKeySpec desKey = new SecretKeySpec("12345678".getBytes(StandardCharsets.UTF_8), "DES");
Cipher instance = Cipher.getInstance("DES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
instance.init(Cipher.ENCRYPT_MODE, desKey, iv);
byte[] doFinal = instance.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
ByteString of = ByteString.of(doFinal);
String hex = of.hex();
String base64 = of.base64();
return hex + "||" + base64;
}
public static String des_decrypt_CBC(byte[] cipherBytes) throws Exception {
SecretKeySpec desKey = new SecretKeySpec("12345678".getBytes(StandardCharsets.UTF_8), "DES");
Cipher instance = Cipher.getInstance("DES/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
instance.init(Cipher.DECRYPT_MODE, desKey, iv);
byte[] doFinal = instance.doFinal(cipherBytes);
return new String(doFinal);
}DESede (3DES)
Code
public static String DESede_encrypt(String plainText) throws Exception {
SecretKeySpec desKey = new SecretKeySpec("123456781234567812345678".getBytes(), "DESede");
Cipher instance = Cipher.getInstance("DESede/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
instance.init(Cipher.ENCRYPT_MODE, desKey, iv);
byte[] doFinal = instance.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
ByteString of = ByteString.of(doFinal);
String hex = of.hex();
String base64 = of.base64();
return hex + "||" + base64;
}
public static String DESede_decrypt(byte[] cipherBytes) throws Exception {
SecretKeySpec desKey = new SecretKeySpec("123456781234567812345678".getBytes(StandardCharsets.UTF_8), "DESede");
Cipher instance = Cipher.getInstance("DESede/CBC/PKCS5Padding");
IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
instance.init(Cipher.DECRYPT_MODE, desKey, iv);
byte[] doFinal = instance.doFinal(cipherBytes);
return new String(doFinal);
}AES
Code
public static String AES_encrypt(String plainText) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec("0123456789abcdef".getBytes(), "AES");
Cipher instance = Cipher.getInstance("AES/ECB/PKCS5Padding");
instance.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] doFinal = instance.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
ByteString of = ByteString.of(doFinal);
String hex = of.hex();
String base64 = of.base64();
return hex + "||" + base64;
}
public static String AES_decrypt(byte[] cipherBytes) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec("0123456789abcdef".getBytes(), "AES");
Cipher instance = Cipher.getInstance("AES/ECB/PKCS5Padding");
instance.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] doFinal = instance.doFinal(cipherBytes);
return new String(doFinal);
}Asymmetric Encryption (RSA)
RSA Code
public static PublicKey generatePublic(String publicKeyBase64) throws Exception {
byte[] bytes = ByteString.decodeBase64(publicKeyBase64).toByteArray();
X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
public static PrivateKey generatePrivate(String privateKeyBase64) throws Exception {
byte[] bytes = ByteString.decodeBase64(privateKeyBase64).toByteArray();
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
public static String RSAPublicEncrypt(String plainText) throws Exception {
PublicKey publicKey = generatePublic(BEGIN_PUBLIC_KEY);
Cipher instance = Cipher.getInstance("RSA/ECB/PKCS1Padding");
instance.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] doFinal = instance.doFinal(plainText.getBytes());
return ByteString.of(doFinal).base64();
}
public static String RSAPrivateDecrypt(byte[] cipherBytes) throws Exception {
PrivateKey privateKey = generatePrivate(BEGIN_PRIVATE_KEY);
Cipher instance = Cipher.getInstance("RSA/ECB/PKCS1Padding");
instance.init(Cipher.DECRYPT_MODE, privateKey);
byte[] doFinal = instance.doFinal(cipherBytes);
return new String(doFinal);
}Summary
The article covered three major categories of encryption algorithms commonly used in Java: message‑digest (MD5, SHA‑1, MAC), symmetric (DES, DESede/3DES, AES), and asymmetric (RSA). It demonstrated how to generate these algorithms via MessageDigest, Mac, and Cipher classes and provided ready‑to‑run Android code snippets for each.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Python Crawling & Data Mining
Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
