首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android - SMS检索API -计算应用程序的哈希字符串问题

Android - SMS检索API -计算应用程序的哈希字符串问题
EN

Stack Overflow用户
提问于 2018-12-19 10:15:51
回答 15查看 27.6K关注 0票数 21

我是Android系统中的新手,我正在尝试在我的应用程序中实现使用OTP的SMS检索API。

我正在遵循以下指南:字符串

不幸的是,我被困在“计算应用程序的散列字符串”中

我在这里引用指导部分,下面每一节-我的问题:

  1. 获取应用程序的公钥证书作为小写十六进制字符串。例如,要从密钥存储库获取十六进制字符串,请键入以下命令 keytool -alias MyAndroidKey -exportcert -keystore MyProduction.keystore区xxd -p \ tr -d ":space:“

在哪里可以找到我的“公钥证书”,我应该在哪里运行这个命令?

  1. 计算组合字符串的SHA-256和。

SHA-256是什么?计算它意味着什么?

  1. Base64 64-编码SHA-256和的二进制值。您可能需要首先从它的输出格式解码SHA-256和。

不明白,我在这里该怎么办?

EN

回答 15

Stack Overflow用户

发布于 2019-02-07 15:59:16

谷歌已经创建了剧本来包装必要的CLI命令来生成应用哈希。

用法是:

代码语言:javascript
复制
./sms_retriever_hash_v9.sh --package "com.your.packagename" --keystore /path/to/your.keystore

示例输出:

代码语言:javascript
复制
$ ./sms_retriever_hash_v9.sh --package "com.your.packagename" --keystore debug.keystore

package name: com.your.packagename
keystore file: debug.keystore

File debug.keystore is found.

Enter keystore password:  


certificate in hex: 3082030d308201f5a003020102020475125fad300d06092a864886f70d01010b05003037310b30090603550406130255533110300e060355040a1307416e64726f6964311630140603550403130d416e64726f6964204465627567301e170d3135313132333231323734355a170d3435313131353231323734355a3037310b30090603550406130255533110300e060355040a1307416e64726f6964311630140603550403130d416e64726f696420446562756730820122300d06092a864886f70d01010105000382010f003082010a0282010100c7604e3b464d0c3f1b556aecfbfcd60b35bb8274909c3eac8825d909b47d44ad60f3dcbd3bdb270a91ed09a8f4c7d39a7da51519116ab2085fdc5761ab472c53860e71779dbf1ebdb5ce2d0140197ac9bcc6ab0e249440be09e233885b110a0fce4b04c903b7741cbc31207ceeb55f71f02b59c2771986238972610cf33e472c08d3b67147117f356617357300dac2655cfa3c056fcc12aa5837a22f9af82164008aae32564db25c2801a45cb66bc087fa8710d14f6448446bc43fb5938c30306959eb5e03dee3dfaf1c83d684338c213208b94a6ea2aa937ba00dd800cbe5b6e30a5a3752b95e5948b20eb6a7051768395e498d12cf2e507458e14e9433d7d70203010001a321301f301d0603551d0e04160414efd057879cfb3ed6c9122caa5d26a6da5f59aadd300d06092a864886f70d01010b0500038201010074004b26417b91333a0503e505030784172a5ac5ffa68d02d42f5991fa637365a3c4833707d062063210da0c16f32be730081420b4ec9563475a57f02f2bf0364cbdc01154e9921edd5140bb4218d7ec6fd3f062d1acacc7cc005c64b7f7e362601fea2a7571c395ecf071a0f10a1bf3c44aa874eb61375e11308ec318c81f4bbd701de2d2fcbbbf764507074da570636f740b379652afe386eb48f69407074b096f3ce03e1d7ac50d9b79169132b01d75389959255b530549a3179798503c83e153e6feb78a89ef80bfce197e23314740f1d55a0db140eb2a44d3acce82d41503b180b6e8ed28f2411f750f9308c72cd8867486ad64af593bc1f1fff5b30510

SHA-256 output in hex: 20e861ecc8550c1e608efc3006f82278025d5e3d7169b40c72b8c3dd0aa9cfd9

First 8 bytes encoded by base64: IOhh7MhVDB5

SMS Retriever hash code:  IOhh7MhVDB5

原始脚本文件保存在本地,然后运行chmod u+x sms_retriever_hash_v9.sh使其可执行。

如果指向脚本的链接消失,以下是脚本内容:

代码语言:javascript
复制
#!/bin/sh

# ------------------------------------------------------------------
# [Author] Title
#          Description
# ------------------------------------------------------------------

VERSION=0.1.0
SUBJECT=sms-retriever-hash-generator
USAGE="Usage: sms_retriever_hash_v9.sh --package package_name --keystore keystore_file"

# --- Options processing -------------------------------------------
if [ $# == 0 ] ; then
    echo $USAGE
    exit 1;
fi

# USE: apkblacklister.sh --source source.apk --target target.apk more files to scan

if [[ "$1" != "--package" ]]; then
  echo "Error: expected --package as first parameter"
  exit 1
fi
pkg="$2"
shift 2

if [[ "$1" != "--keystore" ]]; then
  echo "Error: expected --keystore as third parameter"
  exit 1
fi
keystore="$2"
shift 2



echo
echo "package name: $pkg"
echo "keystore file: $keystore"
echo 

if [ -e "$keystore" ]
then
  echo "File $keystore is found."
  echo
else
  echo "File $keystore is not found."
  echo
  exit 0;
fi

# Retrieve certificate from keystore file. Decoded with Base64 and converted to hex
cert=$(keytool -list -rfc -keystore $keystore | sed  -e '1,/BEGIN/d' | sed -e '/END/,$d' | tr -d ' \n' | base64 --decode | xxd -p | tr -d ' \n')

echo
echo "certificate in hex: $cert"


# concatenate input
input="$pkg $cert"

# 256 bits = 32 bytes = 64 hex chars
output=$(printf "$input" | shasum -a 256 | cut -c1-64)
echo
echo "SHA-256 output in hex: $output"

# take the beginning 72 bits (= 9 bytes = 18 hex chars)
output=$(printf $output | cut -c1-18)

# encode sha256sum output by base64 (11 chars)
base64output=$(printf $output | xxd -r -p | base64 | cut -c1-11)
echo
echo "First 8 bytes encoded by base64: $base64output"
echo
echo "SMS Retriever hash code:  $base64output"
echo
票数 40
EN

Stack Overflow用户

发布于 2019-01-05 12:49:38

代码语言:javascript
复制
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.os.Build;
import android.util.Base64;
import android.util.Log;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
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 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.
*/

public class AppSignatureHelper extends ContextWrapper {
    public static final String TAG = AppSignatureHelper.class.getSimpleName();
    private static final String HASH_TYPE = "SHA-256";
    public static final int NUM_HASHED_BYTES = 9;
    public static final int NUM_BASE64_CHAR = 11;

    public AppSignatureHelper(Context context) {
        super(context);
        getAppSignatures();
    }

    /**
     * Get all the app signatures for the current package
     * @return
     */
    public ArrayList<String> getAppSignatures() {
        ArrayList<String> appCodes = new ArrayList<>();

        try {
            // Get all package signatures for the current package
            String packageName = getPackageName();
            PackageManager packageManager = getPackageManager();
            Signature[] signatures = packageManager.getPackageInfo(packageName,
                    PackageManager.GET_SIGNATURES).signatures;

            // For each signature create a compatible hash
            for (Signature signature : signatures) {
                String hash = hash(packageName, signature.toCharsString());
                if (hash != null) {
                    appCodes.add(String.format("%s", hash));
                }

                Log.v(TAG, "Hash " + hash);

            }
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "Unable to find package to obtain hash.", e);
        }
        return appCodes;
    }

    private static String hash(String packageName, String signature) {
        String appInfo = packageName + " " + signature;
        try {
            MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8));
            }
            byte[] hashSignature = messageDigest.digest();

            // truncated into NUM_HASHED_BYTES
            hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES);
            // encode into Base64
            String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP);
            base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR);

            Log.d(TAG, String.format("pkg: %s -- hash: %s", packageName, base64Hash));
            return base64Hash;
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "hash:NoSuchAlgorithm", e);
        }
        return null;
    }
}

在项目中添加上述类,然后从LoginActivity调用它,如下所示:

代码语言:javascript
复制
AppSignatureHelper appSignatureHelper = new AppSignatureHelper(LoginActivity.this);

通过这种方式,您将得到11位数字的散列,您将能够获得如下所示:

代码语言:javascript
复制
Log.v(TAG, appSignatureHelper.getAppSignatures().get(0));
票数 22
EN

Stack Overflow用户

发布于 2019-02-06 08:56:24

代码语言:javascript
复制
First way:

如果您想为在play存储上签名的应用程序制作散列字符串sms,那么从play商店下载应用程序签名证书。进入发布管理->应用程序签名,该文件夹将被称为deployment_cer.der:

然后使用以下代码将此.der文件更改为jks文件

代码语言:javascript
复制
keytool -importcert -alias examplealias -file deployment_cert.der -keystore certificate.jks -storepass examplepass

信任证书,您就可以使用证书而不是keystore了。

现在有了live的certificate.jks,您可以使用下面的代码生成11哈希字符串:

代码语言:javascript
复制
keytool -exportcert -alias anything -keystore '/home/adminuser/Documents/user/certificate.jks' | xxd -p | tr -d "[:space:]" | echo -n com.example.firstapp `cat` | sha256sum | tr -d "[:space:]-" | xxd -r -p | base64 | cut -c1-11 

输入密码,然后哈希字符串将显示上传的实时版本apk。

如果您正在linux上工作,这些代码就是。现在,如果您想在windows上工作,可以从可以在这里下载的文件中替换xxd和tr。

备注:如果您想在上传到存储之前测试应用程序,那么使用您的密钥存储库更改密钥存储库,如果您没有转换的.jks文件

第二条路:

您可以在应用程序中创建一个类来生成代码。

代码语言:javascript
复制
public class SmsVerification extends ContextWrapper {
public static final String TAG = SmsVerify.class.getSimpleName();

private static final String HASH_TYPE = "SHA-256";
public static final int NUM_HASHED_BYTES = 9;
public static final int NUM_BASE64_CHAR = 11;

public SmsVerification (Context context) {
    super(context);
}

/**
 * Get all the app signatures for the current package
 * @return
 */
public ArrayList<String> getAppSignatures() {
    ArrayList<String> appCodes = new ArrayList<>();

    try {
        // Get all package signatures for the current package
        String packageName = getPackageName();
        PackageManager packageManager = getPackageManager();
        Signature[] signatures = packageManager.getPackageInfo(packageName,
                PackageManager.GET_SIGNATURES).signatures;

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

private static String hash(String packageName, String signature) {
    String appInfo = packageName + " " + signature;
    try {
        MessageDigest messageDigest = MessageDigest.getInstance(HASH_TYPE);
        messageDigest.update(appInfo.getBytes(StandardCharsets.UTF_8));
        byte[] hashSignature = messageDigest.digest();

        // truncated into NUM_HASHED_BYTES
        hashSignature = Arrays.copyOfRange(hashSignature, 0, NUM_HASHED_BYTES);
        // encode into Base64
        String base64Hash = Base64.encodeToString(hashSignature, Base64.NO_PADDING | Base64.NO_WRAP);
        base64Hash = base64Hash.substring(0, NUM_BASE64_CHAR);

        Log.d(TAG, String.format("pkg: %s -- hash: %s", packageName, base64Hash));
        return base64Hash;
    } catch (NoSuchAlgorithmException e) {
        Log.e(TAG, "hash:NoSuchAlgorithm", e);
    }
    return null;
}

并调用类中的函数:

代码语言:javascript
复制
ArrayList<String> appCodes = new ArrayList<>();
SmsVerify hash = new SmsVerify(activity);
appCodes= hash.getAppSignatures();
String yourhash = appCodes.get(0);
票数 17
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53849023

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档