java - 如何读取 rsa 公钥形式字符串(由 java 生成,我想用 Python 读取它)

标签 java python-3.x rsa public-key-encryption

生成公钥的代码是

    public static final String CHARSET = "UTF-8";
    public static final String RSA_ALGORITHM = "RSA";


    public static Map<String, String> createKeys(int keySize){
        KeyPairGenerator kpg;
        try{
            kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        }catch(NoSuchAlgorithmException e){
            throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
        }

        kpg.initialize(keySize);

        KeyPair keyPair = kpg.generateKeyPair();

        Key publicKey = keyPair.getPublic();
        String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());

        Key privateKey = keyPair.getPrivate();
        String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
        Map<String, String> keyPairMap = new HashMap<String, String>();
        keyPairMap.put("publicKey", publicKeyStr);
        keyPairMap.put("privateKey", privateKeyStr);

        return keyPairMap;
    }


    public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
        return key;
    }

然后 key 发送给我,我想用 python importKey() 读取它。但我总是收到错误“不支持 RSA key 格式”。

关键是“MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDGrLFBqubzi45M_yxs5Ps4XW3DIOeAo5x7Ca9EYmWAig3Rb3Efm2PCgipwNube2Ae5eUI5dYlQW32FSF81rw7vNdwfODDzITyWRPLEuVbBb kF5zD6kTxycqlVbH-uTyb95181jpY_XY6tmEOCZCq3mZhil9VA4ZvAoSBcJ8muXaQIDAQAB"

用 Google 搜索后,我尝试向其添加 header “-----BEGIN RSA PUBLIC KEY-----”,但没有任何不同。

最佳答案

  1. 您正在使用“URLsafe”base64 编码器,尽管不是标准的 Java 编码器。 “URLsafe”使用不同的字符(对于代码值 62 和 63),没有填充,也没有换行符。 PEM 格式(早在 URLsafe 编码出现之前就已设计,实际上是在 URL 出现之前一年多!)使用传统的 Base64 字符(现在主要与 MIME 相关)、填充和换行(每 64 个字符)。尽管并非所有软件都会检查换行符;你没有说你正在使用哪个Python加密库(有几个),所以我无法检查它是否关心这一点。

    在 Java 8 中,您可以使用 Base64.getMimeEncoder()来处理其中的大部分,但如果您坚持使用较旧的 Java(见下文)和/或其他一些库,则必须提供有关它的详细信息。您可以将 - _ 字符转换为 +/,将 = 填充添加为 4 的倍数,然后添加如果需要的话换行。

    OTOH我看过的Python库接受'DER'(即二进制)以及PEM,所以你可以解码base64(许多解码器可以处理缺少填充的情况,至少有些解码器可以使用或处理两种字符集没有规范)并按原样使用。

  2. Java 使用的公钥编码(它不准确地称为“X.509”)以​​及 OpenSSL 和其他一些东西使用的公钥编码是通用的,并且包含算法标识符,因此正确的 PEM标签是 -----BEGIN PUBLIC KEY----------END PUBLIC KEY----- (没有 RSA )。

  3. 你没有说你使用什么Java,但它显然默认为RSA的1024位,这已经过时了好几年,并且不再被认为能提供足够的安全裕度(尽管没有公开的报告) 实际上打破它)。 2048 现在被广泛认为是最小值,某些应用程序或环境出于各种原因使用更多。但是,决定使用哪些加密参数(以及您的应用程序是否应该使用 RSA,如果是的话,使用哪种变体)并不是编程问题,也不是 SO 的题外话;它们属于 crypto.SX (了解基本原则)或security.SX (对于应用程序)。

关于java - 如何读取 rsa 公钥形式字符串(由 java 生成,我想用 Python 读取它),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59080895/

相关文章:

JAVA - 如何从扫描仪读取文件中检测到 "\n"字符

java - 使用 Map 的方法 "getOrDefault()"

java - 如何在不阻塞第一个输入的情况下运行命令行 FFMPEG 并接受多个管道(视频和音频)?

c# - RSA 在 C# (.NET 3.5) 中解密数据,在 php 5.3.2 中用 openssl 加密

java - 在 Java 客户端中使用从 C 服务器接收的公钥

java - 向 DMN 表添加新规则时验证 DMN 规则不重叠

python - -0.0 和 +0.0 之间有区别吗?

python - Boto:从配置中动态获取 Python 代码中的 aws_access_key_id 和 aws_secret_access_key?

python - 如何在从elasticsearch导出的CSV文件中打印列名?

c# - 在 .NET 中使用 PEM 编码的 RSA 私钥