You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android验证RSA-SHA512签名遇ASN.1编码错误求助

RSA-SHA512签名验证的ASN.1编码错误排查与解决

问题背景

我尝试使用public.cer验证.pass文件的签名,签名算法为带PKCS1填充的RSA-SHA512,目标SDK版本32。编写的验证方法在解析证书时抛出ASN.1编码错误,同时想确认PKCS1填充是否需要额外配置。

验证方法代码

public boolean validateSignature(Context context, byte[] data, byte[] signature) {
        try {
            // Reading public certificate from raw folder
            InputStream is = context.getResources().openRawResource(R.raw.public_cer);

            CertificateFactory cf = CertificateFactory.getInstance("X.509");

            // This line is giving error
            X509Certificate crt = (X509Certificate) cf.generateCertificate(is);

            PublicKey publicKey = crt.getPublicKey();

            Signature sig = Signature.getInstance("SHA512withRSA");
            sig.initVerify(publicKey);
            sig.update(data);

            return sig.verify(Base64.decode(signature, Base64.NO_WRAP));
        } catch (Exception ex) {

             Log.d(TAG, ex.getLocalizedMessage());
        }

        return false;
    }

调用代码

if (validateSignature(
                applicationContext,
                bytes, // Byte array of Data file
                signatureBytes // Byte array of signature file
            )
        ) {
            Log.d(TAG, "checkSignature: true");
        } else {
            Log.d(TAG, "checkSignature: false");
        }

错误信息

com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0c0000be:ASN.1 encoding routines:OPENSSL_internal:WRONG_TAG


问题解答

关于PKCS1填充的配置

不需要额外配置。SHA512withRSA在Java/Android环境中默认采用PKCS#1 v1.5填充,完全匹配你的算法要求,这部分代码逻辑是正确的。

ASN.1编码错误的原因与修复

错误WRONG_TAG的核心是系统无法正确解析public.cer文件,以下是具体排查和修复步骤:

1. 检查证书文件格式与完整性

  • 确认证书是标准X.509格式:
    • PEM格式证书需包含首尾标记:-----BEGIN CERTIFICATE-----和-----END CERTIFICATE-----,中间为Base64编码内容
    • DER格式是二进制文件,不可用文本编辑器修改,避免引入多余字符
  • 用OpenSSL工具验证证书有效性:
    openssl x509 -in public.cer -text -noout
    
    若命令能输出证书详细信息则证书有效;若报错,说明证书损坏或格式错误,需重新获取正确的公钥证书。

2. 适配PEM格式证书的读取逻辑

如果你的public.cer是PEM格式,直接用CertificateFactory读取会失败,需先去除首尾标记再解码:

public boolean validateSignature(Context context, byte[] data, byte[] signature) {
    try {
        InputStream is = context.getResources().openRawResource(R.raw.public_cer);
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder pemContent = new StringBuilder();
        String line;
        boolean inCertBlock = false;
        
        while ((line = reader.readLine()) != null) {
            if (line.startsWith("-----BEGIN CERTIFICATE-----")) {
                inCertBlock = true;
                continue;
            }
            if (line.startsWith("-----END CERTIFICATE-----")) {
                inCertBlock = false;
                break;
            }
            if (inCertBlock) {
                pemContent.append(line.trim());
            }
        }
        
        byte[] certBytes = Base64.decode(pemContent.toString(), Base64.DEFAULT);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate crt = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certBytes));

        PublicKey publicKey = crt.getPublicKey();

        Signature sig = Signature.getInstance("SHA512withRSA");
        sig.initVerify(publicKey);
        sig.update(data);

        return sig.verify(Base64.decode(signature, Base64.NO_WRAP));
    } catch (Exception ex) {
        Log.d(TAG, ex.getLocalizedMessage());
        ex.printStackTrace();
    }
    return false;
}

3. 确认签名数据的正确性

确保signatureBytes是签名的原始二进制数据,或正确解码后的字节数组:

  • 若签名文件是Base64文本格式,需先读取文本内容再调用Base64.decode,而非直接读取二进制文件。

内容的提问来源于stack exchange,提问作者Niral Bhavsar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 22:40:57