Mac下获取android studio keystore的SHA1和MD5

本文介绍如何使用keytool命令在Android Studio的Terminal工具中获取debug.keystore和其他keystore文件的SHA1和MD5指纹。这些步骤对于验证应用签名一致性至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


在Android studio中打开Terminal工具、

获取 debug.keystore 的SHA1、MD5:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android


获取其他 keystore 的SHA1、MD5:
keytool -list -v -keystore ~/Desktop/agency.jks -alias 别名 -storepass 密码 -keypass 密码


打包界面作为参考:





<think>我们之前讨论的是在Bitwasp库中获取非压缩公钥(04开头)的方法,使用`getUncompressed()`函数。但现在用户遇到的问题是缺少这个函数,可能是因为库版本不同或者使用的库不支持此方法。根据用户提供的引用,他们可能是在Android开发或uniapp环境中处理证书公钥,而不是之前的PHP环境。因此,我们需要调整解决方案以适应新环境。 用户引用中提到了通过keytool命令获取公钥,以及通过APK分析工具获取公钥MD5。但用户的核心问题仍然是:如何在没有`getUncompressed()`函数的情况下获得非压缩公钥。 解决方案思路: 1. 如果用户是在PHP环境中使用Bitwasp库,那么检查库版本并更新,或者使用其他方法(如手动计算)来获取非压缩公钥。 2. 如果用户是在Android或uniapp环境中,那么可以使用Java或命令行工具(如keytool)来获取公钥,并确保公钥是非压缩格式。 由于用户引用中多次出现keytool命令,我们假设用户现在是在Android开发环境中需要非压缩公钥(可能是为了备案等需求)。因此,我们将重点放在如何使用命令行工具获取非压缩公钥。 但是,需要注意的是,keytool默认导出的证书公钥是X.509格式,而不是我们之前讨论的椭圆曲线公钥的原始格式(即04开头的65字节公钥)。因此,我们需要将X.509格式的公钥转换为所需的原始公钥。 步骤: 1. 使用keytool导出证书(cer文件): ```shell keytool -export -alias your_alias -file certificate.cer -keystore your_keystore.keystore ``` 2. 使用OpenSSL工具从证书中提取公钥,并将其转换为非压缩格式的椭圆曲线公钥(即04开头的十六进制字符串)。 然而,OpenSSL默认导出的公钥也是PEM格式(X.509),我们需要进一步处理。 详细步骤: 步骤1:导出证书(cer文件) 步骤2:使用OpenSSL将cer文件转换为PEM格式(如果已经是PEM则跳过) 步骤3:从PEM文件中提取公钥(仍然是X.509格式) 步骤4:将X.509格式的公钥转换为非压缩的椭圆曲线公钥(04开头) 但是,OpenSSL没有直接输出非压缩公钥的命令。因此,我们需要: - 首先,从X.509公钥中提取出椭圆曲线公钥点(x,y坐标) - 然后,手动拼接成04开头的字符串。 我们可以使用以下命令(需要OpenSSL支持): 1. 将cer文件转换为PEM格式(如果证书是DER格式): ```shell openssl x509 -inform der -in certificate.cer -out certificate.pem ``` 2. 从PEM文件中提取公钥(PEM格式): ```shell openssl x509 -pubkey -noout -in certificate.pem > pubkey.pem ``` 3. 提取公钥的十六进制表示(但这是PEM格式,不是原始公钥点): 我们需要进一步解析这个公钥。实际上,我们可以使用OpenSSL的`asn1parse`命令来解析公钥,然后提取出比特字符串(即公钥点)。但是,对于椭圆曲线公钥,这个比特字符串就是压缩或非压缩格式的公钥。 注意:在X.509证书中,公钥通常以非压缩格式存储(即04开头)。因此,我们提取出的比特字符串应该就是非压缩公钥。 验证:使用以下命令查看公钥的ASN.1结构: ```shell openssl asn1parse -in pubkey.pem ``` 输出中会有一个OID表示椭圆曲线类型(如prime256v1),然后有一个比特字符串(BIT STRING),这个比特字符串的内容就是公钥点。注意,比特字符串的第一个字节是0x04(表示非压缩),后面是xy坐标。 因此,我们可以这样提取: ```shell openssl asn1parse -in pubkey.pem -out pubkey.der ``` 然后使用十六进制查看工具查看pubkey.der文件,或者直接解析。 但是,更简单的方法是使用以下命令直接输出公钥的十六进制: ```shell openssl ec -pubin -in pubkey.pem -text -noout ``` 这个命令会输出公钥的详细信息,包括xy坐标(十六进制)。我们可以将这两个坐标拼接起来,前面加上04,就得到了非压缩公钥。 示例输出: ``` read EC key Public-Key: (256 bit) pub: 04:9d:4d:12:... (很长的一行十六进制,以04开头) ASN1 OID: prime256v1 NIST CURVE: P-256 ``` 注意:输出中的“pub:”后面的部分就是非压缩公钥(以04开头,后面是64字节的xy坐标,共65字节,130个十六进制字符)。 因此,我们可以直接复制这个字符串(去掉冒号)作为非压缩公钥。 但是,如果输出中没有直接给出这个字符串,我们可以手动拼接: - 从输出中找到xy的十六进制(不带冒号,并且注意可能是大端格式,并且可能前面有0x前缀,需要去掉)。 - 然后拼接成:04 + x + y(xy都是32字节,所以总长度为1+32+32=65字节,130个十六进制字符)。 因此,完整的步骤: 1. 导出证书(cer文件) 2. 将cer转换为pem(如果证书是DER格式) 3. 提取公钥到pubkey.pem 4. 使用命令:`openssl ec -pubin -in pubkey.pem -text -noout` 查看公钥信息 5. 从输出中提取非压缩公钥(04开头的字符串)或者手动拼接xy坐标。 注意:如果公钥已经是非压缩格式,那么输出中会直接显示以04开头的字符串(可能中间有冒号,需要去除)。 替代方案(编程实现): 如果用户需要在代码中实现,可以使用Java的加密库来提取非压缩公钥。示例代码如下(Java): ```java import java.security.*; import java.security.cert.*; import java.io.*; public class GetUncompressedPublicKey { public static void main(String[] args) throws Exception { // 加载keystore KeyStore ks = KeyStore.getInstance("JKS"); FileInputStream fis = new FileInputStream("your_keystore.keystore"); ks.load(fis, "keystore_password".toCharArray()); fis.close(); // 获取证书 Certificate cert = ks.getCertificate("your_alias"); PublicKey publicKey = cert.getPublicKey(); // 检查是否是EC公钥 if (publicKey instanceof java.security.interfaces.ECPublicKey) { java.security.interfaces.ECPublicKey ecPublicKey = (java.security.interfaces.ECPublicKey) publicKey; // 获取椭圆曲线点 java.security.spec.ECPoint point = ecPublicKey.getW(); // 获取xy坐标(大整数) java.math.BigInteger x = point.getAffineX(); java.math.BigInteger y = point.getAffineY(); // 将xy转换为固定长度的字节数组(32字节) byte[] xBytes = to32Bytes(x); byte[] yBytes = to32Bytes(y); // 构建非压缩公钥字节数组(0x04 + x + y) byte[] uncompressedPubKey = new byte[1 + 32 + 32]; uncompressedPubKey[0] = 0x04; System.arraycopy(xBytes, 0, uncompressedPubKey, 1, 32); System.arraycopy(yBytes, 0, uncompressedPubKey, 33, 32); // 转换为十六进制字符串 String hex = bytesToHex(uncompressedPubKey); System.out.println(hex); } else { System.out.println("Not an EC public key."); } } // 将大整数转换为32字节的数组(前面补0) private static byte[] to32Bytes(java.math.BigInteger n) { byte[] bytes = n.toByteArray(); if (bytes.length > 32) { // 如果长度超过32字节,则取后32字节(大整数可能是负数,所以前面会有多余的0xFF,但通常公钥坐标是正数,所以应该是前面补0) byte[] result = new byte[32]; System.arraycopy(bytes, bytes.length-32, result, 0, 32); return result; } else if (bytes.length < 32) { // 前面补0 byte[] result = new byte[32]; System.arraycopy(bytes, 0, result, 32 - bytes.length, bytes.length); return result; } return bytes; } // 字节数组转十六进制字符串 private static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); } } ``` 注意:上面的代码适用于椭圆曲线(EC)公钥。在Android备案中,通常使用ECC算法,所以应该是适用的。 总结: 根据用户的环境,有两种方法: 1. 命令行方法(使用OpenSSL)适用于快速获取。 2. 编程方法(使用Java)适用于集成到程序中。 如果用户之前的问题是在PHP环境中,那么可能需要考虑使用PHP的OpenSSL扩展来解析证书,并提取非压缩公钥。但用户引用中提到了uniappAndroid,因此我们提供了命令行Java的解决方案。 注意:在PHP中,也可以使用OpenSSL函数来解析证书并获取公钥,然后进一步处理。但鉴于用户之前的上下文是PHP的Bitwasp库,而现在引用中出现了keytool,我们判断用户可能已经切换了环境。 因此,我们根据用户当前的环境(Android/uniapp)提供了上述方案。 如果用户仍然在PHP环境中,且无法使用`getUncompressed()`,那么我们可以使用PHP的OpenSSL扩展来获取公钥点: ```php // 读取证书文件 $cert = file_get_contents('certificate.cer'); // 解析证书 $pubKey = openssl_pkey_get_public($cert); // 获取公钥细节(包括椭圆曲线点) $details = openssl_pkey_get_details($pubKey); // 对于椭圆曲线公钥,$details['ec']包含xy坐标 if (isset($details['ec'])) { $x = $details['ec']['x']; $y = $details['ec']['y']; // 将xy坐标转换为十六进制,并拼接 $uncompressedPubKey = '04' . bin2hex($x) . bin2hex($y); // 注意:xy坐标应该是32字节,所以总长度应为130个十六进制字符(04+64+64) } ``` 但是,这个方法需要PHP的OpenSSL扩展支持,并且版本足够新(支持椭圆曲线)。 综上所述,我们提供了多种环境下的解决方案,用户可以根据自己的实际环境选择。 最后,生成相关问题: 1. 如何用OpenSSL从证书中提取公钥? 2. 椭圆曲线公钥的压缩非压缩格式有什么区别? 3. 在Android开发中,如何通过代码获取非压缩公钥? 4. 如何将X.509格式的公钥转换为椭圆曲线公钥点? 5. 在PHP中如何解析椭圆曲线证书?</think>### 解决缺少 `getUncompressed()` 函数的公钥格式转换方案 根据您的需求,以下是针对不同场景的完整解决方案,无需依赖 `getUncompressed()` 函数: --- #### 方案一:通过命令行工具获取非压缩公钥(推荐) 适用于 Android App 备案证书管理场景[^1][^2] ```bash # 1. 导出公钥证书(X.509格式) keytool -export -alias your_alias -file public_key.cer -keystore your_cert.keystore # 2. 将DER格式转换为PEM格式 openssl x509 -inform der -in public_key.cer -out public_key.pem # 3. 提取非压缩格式公钥(04开头) openssl ec -pubin -in public_key.pem -text -noout | awk '/pub:/{flag=1;next} /ASN1/{flag=0} flag' | tr -d ':\n' | sed 's/^04//; s/.*/04&/' ``` **执行说明**: 1. 替换 `your_alias` `your_cert.keystore` 为实际 2. 最终输出为 130 字符的十六进制字符串(04开头) 3. 此方法适用于所有支持 OpenSSL 的平台 --- #### 方案二:编程实现公钥格式转换(Python) 适用于需要代码集成的场景 ```python from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import ec def convert_to_uncompressed(compressed_pubkey: str) -> str: """ 将压缩公钥(02/03开头)转换为非压缩格式(04开头) :param compressed_pubkey: 66字符的十六进制压缩公钥 :return: 130字符的非压缩公钥 """ # 验证输入格式 if len(compressed_pubkey) != 66 or compressed_pubkey[:2] not in ("02", "03"): raise ValueError("无效的压缩公钥格式") # 从压缩格式重建公钥 public_key = ec.EllipticCurvePublicKey.from_encoded_point( curve=ec.SECP256K1(), data=bytes.fromhex(compressed_pubkey) ) # 转换为非压缩格式 uncompressed = public_key.public_bytes( encoding=serialization.Encoding.X962, format=serialization.PublicFormat.UncompressedPoint ) return uncompressed.hex() # 使用示例 compressed_key = "02b4632d08485ff1df2db55b9dafdb233efa3a5a8f8f3a1dd6f3b2b0a1d2e7f3e1" uncompressed_key = convert_to_uncompressed(compressed_key) print(f"非压缩公钥: {uncompressed_key}") # 输出04开头的130字符 ``` **依赖安装**: ```bash pip install cryptography ``` --- #### 方案三:通过 APK 文件直接获取Android 备案) 适用于已打包的 Android 应用[^3] 1. 下载并安装 [APK Analyzer](https://developer.android.com/studio/debug/apk-analyzer) 2. 打开 APK 文件 3. 导航到 `APK Signature` 部分 4. 直接获取: - **平台公钥**:非压缩格式(04开头) - **签名 MD5 **:用于备案 --- #### 常见问题解决 | 问题类型 | 解决方案 | |---------|---------| | `keytool not found` | 安装 JDK 并配置环境变量 | | 证书密码错误 | 通过 Uniapp 云端查看证书信息[^1] | | 缺少 OpenSSL | Windows: 安装 [Git Bash](https://gitforwindows.org/) <br> Mac: `brew install openssl` | | Python 环境问题 | 使用 `python -m pip install cryptography` | > **关键提示**:根据椭圆曲线密码学原理,压缩公钥(02/03开头)包含完整坐标信息,可通过数学计算还原非压缩格式[^1]。转换公式为: > $$ y = \sqrt{x^3 + 7} \mod p $$ > 其中 $p$ 是 secp256k1 曲线的质数 ($2^{256} - 2^{32} - 977$) --- #### 备案所需关键信息获取 1. **公钥**:使用方案一或方案三获取 2. **MD5/SHA1/SHA256**: ```bash keytool -list -v -keystore your_cert.keystore ``` 3. **包名**:通过方案三的 APK Analyzer 查看 `AndroidManifest.xml` > 推荐使用 Uniapp 云端管理证书,可直接查看所有备案所需信息[^1][^2]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值