App Signature helper class (Kotlin)

Appcaesars
2 min readFeb 23, 2021

This example class will help you to get your applications signature which is a 11- digit hashed code.

import android.content.Context
import android.content.ContextWrapper
import android.content.pm.PackageManager
import android.util.Base64
import timber.log.Timber
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
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,
PackageManager.GET_SIGNATURES).signatures

// 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 = AppSignatureHelper::class.java.simpleName
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)
messageDigest.update(appInfo.toByteArray(StandardCharsets.UTF_8))
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
}
}
}

Friendly Reminder : This signature is only changed when you change your build variant. For example: When you change your application from debug to release variance the signature will be changed or any other variance you created.

Have a nice development day :)

--

--