package expo.modules.otpretriever.utils import android.content.Context import android.content.ContextWrapper import android.content.pm.PackageManager import android.content.pm.Signature import android.util.Base64 import android.util.Log import java.nio.charset.StandardCharsets import java.security.MessageDigest import java.security.NoSuchAlgorithmException import java.util.Arrays /** * 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 receive the message callback. * This only works for apps signed with debug keys. For production apps, you must * get your hash from the Google Play Console. */ class AppSignatureHelper(context: Context) : ContextWrapper(context) { companion object { private val TAG = AppSignatureHelper::class.java.simpleName private const val HASH_TYPE = "SHA-256" private const val NUM_HASHED_BYTES = 9 private const val NUM_BASE64_CHAR = 11 } /** * Get all the app signatures for the current package */ fun getAppSignatures(): ArrayList { val appSignatures = ArrayList() 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 = getHash(packageName, signature) if (hash != null) { appSignatures.add(String.format("%s", hash)) } } } catch (e: PackageManager.NameNotFoundException) { Log.e(TAG, "Unable to find package to obtain signatures", e) } return appSignatures } /** * Hash the signature of the package in a suitable format for verification */ private fun getHash(packageName: String, signature: Signature): String? { val appInfo = "$packageName ${signature.toCharsString()}" try { val messageDigest = MessageDigest.getInstance(HASH_TYPE) messageDigest.update(appInfo.toByteArray(StandardCharsets.UTF_8)) // Truncate the hash val hashBytes = Arrays.copyOfRange( messageDigest.digest(), 0, NUM_HASHED_BYTES ) // Base64 encode the hash val base64Hash = Base64.encodeToString( hashBytes, Base64.NO_PADDING or Base64.NO_WRAP ) return base64Hash } catch (e: NoSuchAlgorithmException) { Log.e(TAG, "Hash error: ${e.message}") } return null } }