App Signature helper class (Kotlin)

import android.content.Context
import android.content.ContextWrapper
import android.util.Base64
import timber.log.Timber
import java.nio.charset.StandardCharsets
import java.util.*

* This is a helper class to generate your message hash to be included in your SMS message.
* Without the correct hash, your app won't recieve the message callback. This only needs to be
* generated once per app and stored. Then you can remove this helper class from your code.
class AppSignatureHelper(context: Context?) : ContextWrapper(context) {// Get all package signatures for the current package

// For each signature create a compatible hash
* Get all the app signatures for the current package
* @return
val appSignatures: ArrayList<String>
get() {
val appCodes = ArrayList<String>()
try {
// Get all package signatures for the current package
val packageName = packageName
val packageManager = packageManager
val signatures = packageManager.getPackageInfo(packageName,

// For each signature create a compatible hash
for (signature in signatures) {
val hash = hash(packageName, signature.toCharsString())
if (hash != null) {
appCodes.add(String.format("%s", hash))
} catch (e: PackageManager.NameNotFoundException) {
Timber.e(e, "Unable to find package to obtain hash.")
return appCodes

companion object {
val TAG =
private const val HASH_TYPE = "SHA-256"
const val NUM_HASHED_BYTES = 9
const val NUM_BASE64_CHAR = 11
private fun hash(packageName: String, signature: String): String? {
val appInfo = "$packageName $signature"
try {
val messageDigest = MessageDigest.getInstance(HASH_TYPE)
var hashSignature = messageDigest.digest()

// truncated into NUM_HASHED_BYTES
hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES)
// encode into Base64
var base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING or Base64.NO_WRAP)
base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR)
Timber.e(String.format("pkg: %s -- hash: %s", packageName, base64Hash))
return base64Hash
} catch (e: NoSuchAlgorithmException) {
Timber.e(e, "hash:NoSuchAlgorithm")
return null

Android development

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

A short introduction to select2 v4

How to Create Objects Using Factory Functions in JavaScript

Making an Existing Application More Functional

Part 3(b) — Search Functionality

Weekly Digest 43/2021

Creating a TypeScript tsconfig for nodejs

Performance 101 — I Know How to Load Images

5 JavaScript things you should know

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


Android development

More from Medium

RecycleView Kotlin — Android Studio

Retrofit Overview (Kotlin)

Kotlin with MVVM application PART 4(Last Part)

Open camera and display image using kotlin