• 查看Android打包时签名文件keystore的MD5值


    有些SDK提供方需要我们提供打包APK时使用的包名和签名文件(xxxxxx.jks这个文件)MD5值,然后SDK服务端应该会进行比对保证商户调用的合法性。不然光靠包名是可以伪造的,怎么获取签名文件的MD5值?

    方法一:

    原先通过命令keytool -list -v -keystore test.jks 可以查看md5值,但是发现现在查看不了,只有SHA1和SHA256的

     

    方法二:改成从androidstudio查看

    在app的build.gradle中配置你们签名文件,怎么生成签名文件?

    build-->Generate signed bundle\APK-->next -->Create  new

     

     

     

    android{

    signingConfigs {
        release {
            keyAlias 'test'
            storePassword '666666'
            keyPassword '666666'
            storeFile file('E:\\test.jks')
        }
        debug {
            keyAlias 'test'
            storePassword '666666'
            keyPassword '666666'
            storeFile file('E:\\test.jks')
        }
    }

    }

    右侧gradle Tasks里面双击signingReport就可以查看签名文件的MD5值了

     

    方法三:从PackageInfo类中获取

    1. package com.chinapay.umsfacesdkdemo.utils;
    2. import android.content.Context;
    3. import android.content.pm.PackageInfo;
    4. import android.content.pm.PackageManager;
    5. import android.content.pm.Signature;
    6. import android.util.Log;
    7. import java.security.MessageDigest;
    8. import java.util.ArrayList;
    9. import java.util.HashMap;
    10. /**
    11. * 获取签名工具类
    12. */
    13. public class AppSigning {
    14. public final static String MD5 = "MD5";
    15. public final static String SHA1 = "SHA1";
    16. public final static String SHA256 = "SHA256";
    17. private static HashMap> mSignMap = new HashMap<>();
    18. /**
    19. * 返回一个签名的对应类型的字符串
    20. *
    21. * @param context
    22. * @param type
    23. * @return 因为一个安装包可以被多个签名文件签名,所以返回一个签名信息的list
    24. */
    25. public static ArrayList getSignInfo(Context context, String type) {
    26. if (context == null || type == null) {
    27. return null;
    28. }
    29. String packageName = context.getPackageName();
    30. if (packageName == null) {
    31. return null;
    32. }
    33. if (mSignMap.get(type) != null) {
    34. return mSignMap.get(type);
    35. }
    36. ArrayList mList = new ArrayList();
    37. try {
    38. Signature[] signs = getSignatures(context, packageName);
    39. for (Signature sig : signs) {
    40. String tmp = "error!";
    41. if (MD5.equals(type)) {
    42. tmp = getSignatureByteString(sig, MD5);
    43. } else if (SHA1.equals(type)) {
    44. tmp = getSignatureByteString(sig, SHA1);
    45. } else if (SHA256.equals(type)) {
    46. tmp = getSignatureByteString(sig, SHA256);
    47. }
    48. mList.add(tmp);
    49. }
    50. } catch (Exception e) {
    51. Log.e("e", e.getMessage());
    52. }
    53. mSignMap.put(type, mList);
    54. return mList;
    55. }
    56. /**
    57. * 获取签名sha1值
    58. *
    59. * @param context
    60. * @return
    61. */
    62. public static String getSha1(Context context) {
    63. String res = "";
    64. ArrayList mlist = getSignInfo(context, SHA1);
    65. if (mlist != null && mlist.size() != 0) {
    66. res = mlist.get(0);
    67. }
    68. return res;
    69. }
    70. /**
    71. * 获取签名MD5值
    72. *
    73. * @param context
    74. * @return
    75. */
    76. public static String getMD5(Context context) {
    77. String res = "";
    78. ArrayList mlist = getSignInfo(context, MD5);
    79. if (mlist != null && mlist.size() != 0) {
    80. res = mlist.get(0);
    81. }
    82. return res;
    83. }
    84. /**
    85. * 获取签名SHA256值
    86. *
    87. * @param context
    88. * @return
    89. */
    90. public static String getSHA256(Context context) {
    91. String res = "";
    92. ArrayList mlist = getSignInfo(context, SHA256);
    93. if (mlist != null && mlist.size() != 0) {
    94. res = mlist.get(0);
    95. }
    96. return res;
    97. }
    98. /**
    99. * 返回对应包的签名信息
    100. *
    101. * @param context
    102. * @param packageName
    103. * @return
    104. */
    105. private static Signature[] getSignatures(Context context, String packageName) {
    106. PackageInfo packageInfo = null;
    107. try {
    108. packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_SIGNATURES);
    109. return packageInfo.signatures;
    110. } catch (Exception e) {
    111. Log.e("e", e.toString());
    112. }
    113. return null;
    114. }
    115. /**
    116. * 获取相应的类型的字符串(把签名的byte[]信息转换成16进制)
    117. *
    118. * @param sig
    119. * @param type
    120. * @return
    121. */
    122. private static String getSignatureString(Signature sig, String type) {
    123. byte[] hexBytes = sig.toByteArray();
    124. String fingerprint = "error!";
    125. try {
    126. MessageDigest digest = MessageDigest.getInstance(type);
    127. if (digest != null) {
    128. byte[] digestBytes = digest.digest(hexBytes);
    129. StringBuilder sb = new StringBuilder();
    130. for (byte digestByte : digestBytes) {
    131. sb.append((Integer.toHexString((digestByte & 0xFF) | 0x100)).substring(1, 3));
    132. }
    133. fingerprint = sb.toString();
    134. }
    135. } catch (Exception e) {
    136. Log.e("e", e.toString());
    137. }
    138. return fingerprint;
    139. }
    140. /**
    141. * 获取相应的类型的字符串(把签名的byte[]信息转换成 95:F4:D4:FG 这样的字符串形式)
    142. *
    143. * @param sig
    144. * @param type
    145. * @return
    146. */
    147. private static String getSignatureByteString(Signature sig, String type) {
    148. byte[] hexBytes = sig.toByteArray();
    149. String fingerprint = "error!";
    150. try {
    151. MessageDigest digest = MessageDigest.getInstance(type);
    152. if (digest != null) {
    153. byte[] digestBytes = digest.digest(hexBytes);
    154. StringBuilder sb = new StringBuilder();
    155. for (byte digestByte : digestBytes) {
    156. sb.append(((Integer.toHexString((digestByte & 0xFF) | 0x100)).substring(1, 3)).toUpperCase());
    157. sb.append(":");
    158. }
    159. fingerprint = sb.substring(0, sb.length() - 1).toString();
    160. }
    161. } catch (Exception e) {
    162. Log.e("e", e.toString());
    163. }
    164. return fingerprint;
    165. }
    166. }

    调用上面的 String md5=AppSigning.getMD5(MainActivity.this)就可以了

  • 相关阅读:
    js原理及手写系列
    【云原生Docker系列第三篇】Docker网络模式(在失去的所有人里,我最怀念自己 )
    【毕业设计】 单片机自动写字机器人设计与实现 - 物联网 嵌入式 stm32
    我们又组织了一次欧洲最大开源社区活动,Hugging Face 博客欢迎社区成员发帖、Hugging Chat 功能更新!...
    python pytorch- TextCNN TextRNN FastText Transfermer (中英文)文本情感分类实战(附数据集,代码皆可运行)
    VS Code 和 Python:数据科学的天作之合
    【Linux】在Xilinx平台上实现UVC Gadget(1)
    【学生个人网页设计作品】使用HMTL制作一个超好看的保护海豚动物网页
    系列六、Java垃圾回收器主要有哪些?
    OpenGL入门(四)之纹理Texture
  • 原文地址:https://blog.csdn.net/figo0423/article/details/126176817