Java 如何为otp sms选择哈希签名?

Java 如何为otp sms选择哈希签名?,java,android,android-app-signing,Java,Android,Android App Signing,我正在使用谷歌短信API自动检测OTP。我正在以编程方式生成哈希键。我使用“SHA-256”作为散列类型,但我得到的散列签名与调试和发布环境不同。 当我使用“SHA-256”散列类型生成的散列键时,我的广播接收器检测到短信。 当我使用“MD5”作为散列类型时,我得到的是调试和发布环境的相同散列键。 但是当我用这个散列键发送短信时,广播接收器并没有检测到它 我对散列签名一无所知,我的应用程序在play store上。我想为我的OTP短信选择一个哈希键。我也不知道google play store是

我正在使用谷歌短信API自动检测OTP。我正在以编程方式生成哈希键。我使用“SHA-256”作为散列类型,但我得到的散列签名与调试和发布环境不同。 当我使用“SHA-256”散列类型生成的散列键时,我的广播接收器检测到短信。 当我使用“MD5”作为散列类型时,我得到的是调试和发布环境的相同散列键。 但是当我用这个散列键发送短信时,广播接收器并没有检测到它

我对散列签名一无所知,我的应用程序在play store上。我想为我的OTP短信选择一个哈希键。我也不知道google play store是否会在发布后更改应用程序的哈希键

AppSignatureHelper

 package com.bizlers.turbo.care.android.utils;

import android.annotation.SuppressLint;
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.ArrayList;
import java.util.Arrays;

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);
    }

    public ArrayList<String> getAppSignatures() {
        ArrayList<String> appCodes = new ArrayList<>();

        try {
            // Get all package signatures for the current package
            String packageName = getPackageName();
            PackageManager packageManager = getPackageManager();
            @SuppressLint("PackageManagerGetSignatures")
            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.e(TAG, String.format("pkg: %s -- hash: %s", packageName, base64Hash));
            return base64Hash;

        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "hash:NoSuchAlgorithm", e);
        }
        return null;
    }
}
package com.bizler.turbo.care.android.utils;
导入android.annotation.SuppressLint;
导入android.content.Context;
导入android.content.ContextWrapper;
导入android.content.pm.PackageManager;
导入android.content.pm.Signature;
导入android.util.Base64;
导入android.util.Log;
导入java.nio.charset.StandardCharset;
导入java.security.MessageDigest;
导入java.security.NoSuchAlgorithmException;
导入java.util.ArrayList;
导入java.util.array;
公共类AppSignatureHelper扩展了ContextWrapper{
公共静态最终字符串标记=AppSignatureHelper.class.getSimpleName();
私有静态最终字符串哈希_TYPE=“SHA-256”;
公共静态final int NUM_HASHED_BYTES=9;
公共静态最终int NUM_BASE64_CHAR=11;
public AppSignatureHelper(上下文){
超级(上下文);
}
公共ArrayList getAppSignatures(){
ArrayList appCodes=新的ArrayList();
试一试{
//获取当前包的所有包签名
字符串packageName=getPackageName();
PackageManager PackageManager=getPackageManager();
@SuppressLint(“PackageManagerGetSignatures”)
Signature[]signatures=packageManager.getPackageInfo(packageName,packageManager.GET_signatures);
//为每个签名创建一个兼容的哈希
用于(签名:签名){
String hash=hash(packageName,signature.tocharstring());
如果(hash!=null)appCodes.add(String.format(“%s”,hash));
}
}捕获(PackageManager.NameNotFounde异常){
Log.e(标记“无法找到获取哈希的包”,e);
}
返回应用程序代码;
}
私有静态字符串哈希(字符串packageName、字符串签名){
字符串appInfo=packageName+“”+签名;
试一试{
MessageDigest=MessageDigest.getInstance(哈希类型);
update(appInfo.getBytes(StandardCharsets.UTF_8));
字节[]hashSignature=messageDigest.digest();
//截断为NUM_散列字节
hashSignature=Arrays.copyOfRange(hashSignature,0,NUM\u散列字节);
//编码成Base64
字符串base64Hash=Base64.encodeToString(hashSignature,Base64.NO_PADDING | Base64.NO_WRAP);
base64Hash=base64Hash.substring(0,NUM\u BASE64\u CHAR);
Log.e(TAG,String.format(“pkg:%s--hash:%s”,packageName,base64Hash));
返回base64Hash;
}捕获(无算法异常){
Log.e(标记“hash:NoSuchAlgorithm”,e);
}
返回null;
}
}

根据文档,哈希类型应为“SHA-256”:

文件说: “计算组合字符串的SHA-256和。”

对于在play store上发布应用程序,以下是一篇有用的帖子:


谢谢,这意味着我需要为开发和发布应用程序维护两个不同的哈希键?@ParagRane因为应用程序在调试和发布时的签名不同,所以哈希键会不同。文档说:您不能直接编辑调试签名配置,但您可以配置如何对发布版本进行签名。感谢您的回复。我还需要一个帮助,在Windows10上执行xxd命令时出错。错误是,“xxd”未被识别为内部或外部命令。我已成功添加了certificate.jks。