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.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
How to Implement Common Encryption Algorithms (MD5, SHA, DES, AES, RSA) in Android

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 8

Project

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Hashasymmetricsymmetric
Python Crawling & Data Mining
Written by

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!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.