google 如何验证 Android SHA1 指纹和包?
How does google verify Android SHA1 fingerprints and packages?
我正在尝试让我的 Google 翻译 API 工作,但目前我找不到方法。这就是我在 Google 开发者控制台中设置内容的方式:
我已经使用调试证书设置了我的 SHA1 指纹。和包名-"bg.webmap.wordy"(这是实际名称)。当我尝试拨打电话时,在 JSON 中返回 "ipRefererBlocked" 错误。但是当我删除指纹和包名时,它完美地工作,但是每个人都可以使用这个密钥,所以非常不安全。所以我的问题是身份验证。
当调用 API 时,我的应用程序会自动发送此指纹吗?我应该自己发送吗?如何发送?问题可能出在调试证书中吗?
Will my app automatically send this fingerprint when the API is
called?
不!
Should I send it myself and how?
是的!
在为 android 应用程序设置 API 密钥限制时,您指定了程序包名称和 SHA-1 证书指纹。所以当你向Google发送请求时,你必须在每个请求的header中添加这些信息。
怎么做?
As answered here,你需要从你的代码中得到你的包名和SHA证书,然后添加到请求header.
获取 SHA 证书:
/**
* Gets the SHA1 signature, hex encoded for inclusion with Google Cloud Platform API requests
*
* @param packageName Identifies the APK whose signature should be extracted.
* @return a lowercase, hex-encoded
*/
public static String getSignature(@NonNull PackageManager pm, @NonNull String packageName) {
try {
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
if (packageInfo == null
|| packageInfo.signatures == null
|| packageInfo.signatures.length == 0
|| packageInfo.signatures[0] == null) {
return null;
}
return signatureDigest(packageInfo.signatures[0]);
} catch (PackageManager.NameNotFoundException e) {
return null;
}
}
private static String signatureDigest(Signature sig) {
byte[] signature = sig.toByteArray();
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] digest = md.digest(signature);
return BaseEncoding.base16().lowerCase().encode(digest);
} catch (NoSuchAlgorithmException e) {
return null;
}
}
添加到请求中 header:
java.net.URL url = new URL(REQUEST_URL);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
try {
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Accept", "application/json");
// add package name to request header
String packageName = mActivity.getPackageName();
connection.setRequestProperty("X-Android-Package", packageName);
// add SHA certificate to request header
String sig = getSignature(mActivity.getPackageManager(), packageName);
connection.setRequestProperty("X-Android-Cert", sig);
connection.setRequestMethod("POST");
// ADD YOUR REQUEST BODY HERE
// ....................
} catch (Exception e) {
e.printStackTrace();
} finally {
connection.disconnect();
}
您可以看到完整答案here。
享受编码:)
我正在尝试让我的 Google 翻译 API 工作,但目前我找不到方法。这就是我在 Google 开发者控制台中设置内容的方式:
我已经使用调试证书设置了我的 SHA1 指纹。和包名-"bg.webmap.wordy"(这是实际名称)。当我尝试拨打电话时,在 JSON 中返回 "ipRefererBlocked" 错误。但是当我删除指纹和包名时,它完美地工作,但是每个人都可以使用这个密钥,所以非常不安全。所以我的问题是身份验证。
当调用 API 时,我的应用程序会自动发送此指纹吗?我应该自己发送吗?如何发送?问题可能出在调试证书中吗?
Will my app automatically send this fingerprint when the API is called?
不!
Should I send it myself and how?
是的!
在为 android 应用程序设置 API 密钥限制时,您指定了程序包名称和 SHA-1 证书指纹。所以当你向Google发送请求时,你必须在每个请求的header中添加这些信息。
怎么做?
As answered here,你需要从你的代码中得到你的包名和SHA证书,然后添加到请求header.
获取 SHA 证书:
/**
* Gets the SHA1 signature, hex encoded for inclusion with Google Cloud Platform API requests
*
* @param packageName Identifies the APK whose signature should be extracted.
* @return a lowercase, hex-encoded
*/
public static String getSignature(@NonNull PackageManager pm, @NonNull String packageName) {
try {
PackageInfo packageInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
if (packageInfo == null
|| packageInfo.signatures == null
|| packageInfo.signatures.length == 0
|| packageInfo.signatures[0] == null) {
return null;
}
return signatureDigest(packageInfo.signatures[0]);
} catch (PackageManager.NameNotFoundException e) {
return null;
}
}
private static String signatureDigest(Signature sig) {
byte[] signature = sig.toByteArray();
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] digest = md.digest(signature);
return BaseEncoding.base16().lowerCase().encode(digest);
} catch (NoSuchAlgorithmException e) {
return null;
}
}
添加到请求中 header:
java.net.URL url = new URL(REQUEST_URL);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
try {
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Accept", "application/json");
// add package name to request header
String packageName = mActivity.getPackageName();
connection.setRequestProperty("X-Android-Package", packageName);
// add SHA certificate to request header
String sig = getSignature(mActivity.getPackageManager(), packageName);
connection.setRequestProperty("X-Android-Cert", sig);
connection.setRequestMethod("POST");
// ADD YOUR REQUEST BODY HERE
// ....................
} catch (Exception e) {
e.printStackTrace();
} finally {
connection.disconnect();
}
您可以看到完整答案here。
享受编码:)