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

Android与OpenSSL公钥加密结果不一致的原因排查

问题

在Android中通过以下代码使用PEM格式公钥加密字符串:

public static String encryptDataWithPEM(String data, String publicKeyPEM) {
    try {
        PublicKey publicKey = getPublicKeyFromPEM(publicKeyPEM);
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedData = cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(encryptedData);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

private static PublicKey getPublicKeyFromPEM(String publicKeyPEM) {
    try {
        PEMParser pemParser = new PEMParser(new StringReader(publicKeyPEM));
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        Object pemObject = pemParser.readObject();

        if (pemObject != null) {
            return converter.getPublicKey((org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) pemObject);
        } else {
            throw new IllegalArgumentException("Invalid PEM format: RSA public key expected");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

同时在Debian控制台执行以下OpenSSL命令重复加密操作:

echo -n "Your data to encrypt" | openssl rsautl -encrypt -pubin -inkey public_key.pem | base64

为何Android与OpenSSL的加密结果不同?

原因分析与解决办法

加密结果不一致通常由以下因素导致:

  • 字符编码不统一
    Android代码中data.getBytes()默认采用UTF-8编码,但如果OpenSSL所在系统的默认字符编码不是UTF-8,会导致原始数据的字节数组存在差异。解决办法是在Android代码中明确指定UTF-8编码:

    byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
    
  • Base64编码格式差异
    Android的Base64.getEncoder()输出无换行的标准Base64字符串,而OpenSSL的base64命令默认每64个字符添加换行符,导致最终输出字符串不同。修改OpenSSL命令,添加-A参数输出单行Base64:

    echo -n "Your data to encrypt" | openssl rsautl -encrypt -pubin -inkey public_key.pem | base64 -A
    
  • 公钥格式或解析不匹配
    如果OpenSSL使用的是PKCS#1格式公钥(头为-----BEGIN RSA PUBLIC KEY-----),而Android代码仅支持解析X.509格式公钥(头为-----BEGIN PUBLIC KEY-----),会导致解析出的公钥不一致。可以将OpenSSL的公钥转换为X.509格式:

    openssl rsa -pubin -in public_key.pem -outform PEM -out public_key_x509.pem
    
  • PKCS#1 v1.5填充的随机性(正常现象)
    RSA使用PKCS1Padding时,加密过程会引入随机生成的填充字节,这是安全规范要求的,目的是避免相同明文加密后得到相同密文。因此即使是同一明文、同一公钥,Android和OpenSSL的加密结果不同是正常现象,只要两边都能正确解密即可验证正确性。

内容的提问来源于stack exchange,提问作者Aina T

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 01:25:02