java - 从 String 到 java.security.PublicKey 对象给了我一个非法字符

标签 java base64 public-key

我有这个方法:

public static PublicKey getKey(String key){
    try{
        byte[] byteKey = Base64.getDecoder().decode(key.getBytes());
        X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey);
        KeyFactory kf = KeyFactory.getInstance("RSA");

        return kf.generatePublic(X509publicKey);
    }
    catch(Exception e){
        e.printStackTrace();
    }

        return null;
    }
}

这应该转换一个公钥(来自 Salesforce public key endpoint 的此 JSON 中的 n 属性之一)。我的 key 里应该是kid 208,但是:

getKey("pTSWJvy04hAU7ev7wmaTvpwHsEbseuPl0AlwoxPHnmoOIMATRT0eTqYpLJxDp4BHRFxDTrcUKHKVHGIAVut_-l6nkEI6ALOVW9C5PP9bXwqeHJ5tiGA6AMpaY1LsJJOd2lgExr0LHUPF2TtO4LOVmlptyGPTRSWhmRpPSc5bjGFsyTFr78WmeixjEts9icAUCiBDdpwVw9qVdjJPsufyimqp8os5htm-DB_qKsnRwABVSQRKLw2y7Mr7NP31R07Mpr108dLS5Et8tKnFoiX0MHf5BbA50NG3DtyT27nSa14T0IvSWYJQhxPWXYtuXkVldpbZZn8E2B1VpcDXXGnSPXoPstE9BU7w1RaF31UeEsE8sWDFdHgJMUYMfWjxVhdJB_NaVUt7v0X9QPffXcFPWKUUeVx0g_ONMz0bB_HltFSODWJeAvcZXk14u4sjpKXNIiK8dJzMe0Qn10m5nIdVtxzXfKHiDNobX1dMENDplhDMVk1eYS9x8dh90qt68Q59vKusm6iMjSaXtzwMfqJBwNck41e9Pie2m_cdSu-RIq1u3FScGkezzqNvIuzcse2y-6ApHkkaFMVsNw3CbD87LtVgNusuom38UVC1rS0LeLYFinU3hnFwvB1UCv1_0Cs8CmrOmdifqd25aZIDf5p8f3kowq3QY1mNtdQc9-HgZ3k");

返回一个错误:

java.lang.IllegalArgumentException: Illegal base64 character 5f at java.util.Base64$Decoder.decode0(Base64.java:714) at java.util.Base64$Decoder.decode(Base64.java:526) at testJwt.testJwt.App.getKey(App.java:52) at testJwt.testJwt.App.main(App.java:76)

我能做什么?我做错了什么吗?

最佳答案

您拥有的数据不是完整的 RSA 公钥,而只是模数或“n”值。 “e”值是公钥的另一部分。这是代码片段来说明它。

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;

public class Main {

    public static void main(String[] args) throws Exception {
        String jsonN = "pTSWJvy04hAU7ev7wmaTvpwHsEbseuPl0AlwoxPHnmoOIMATRT0eTqYpLJxDp4BHRFxDTrcUKHKVHGIA" +
                "Vut_-l6nkEI6ALOVW9C5PP9bXwqeHJ5tiGA6AMpaY1LsJJOd2lgExr0LHUPF2TtO4LOVmlptyGPTRSWhmRpPSc5" +
                "bjGFsyTFr78WmeixjEts9icAUCiBDdpwVw9qVdjJPsufyimqp8os5htm-DB_qKsnRwABVSQRKLw2y7Mr7NP31R0" +
                "7Mpr108dLS5Et8tKnFoiX0MHf5BbA50NG3DtyT27nSa14T0IvSWYJQhxPWXYtuXkVldpbZZn8E2B1VpcDXXGnSP" +
                "XoPstE9BU7w1RaF31UeEsE8sWDFdHgJMUYMfWjxVhdJB_NaVUt7v0X9QPffXcFPWKUUeVx0g_ONMz0bB_HltFSO" +
                "DWJeAvcZXk14u4sjpKXNIiK8dJzMe0Qn10m5nIdVtxzXfKHiDNobX1dMENDplhDMVk1eYS9x8dh90qt68Q59vKu" +
                "sm6iMjSaXtzwMfqJBwNck41e9Pie2m_cdSu-RIq1u3FScGkezzqNvIuzcse2y-6ApHkkaFMVsNw3CbD87LtVgNu" +
                "suom38UVC1rS0LeLYFinU3hnFwvB1UCv1_0Cs8CmrOmdifqd25aZIDf5p8f3kowq3QY1mNtdQc9-HgZ3k";
        String jsonE = "AQAB";

        byte [] nBytes = Base64.getUrlDecoder().decode(jsonN);
        byte [] eBytes = Base64.getUrlDecoder().decode(jsonE);

        BigInteger n = new BigInteger(1, nBytes); // need to use the sign-magnitude constructor
        BigInteger e = new BigInteger(1, eBytes);

        RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec(n, e);
        KeyFactory rsaKeyFactory = KeyFactory.getInstance("RSA");
        PublicKey rsaPub = rsaKeyFactory.generatePublic(rsaPublicKeySpec);
        System.out.println(rsaPub);
    }
}

我不会手动执行此操作,而是会寻找一个已经执行此操作的库,尽管库推荐在 stackoverflow 上是偏离主题的。

关于java - 从 String 到 java.security.PublicKey 对象给了我一个非法字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45148340/

相关文章:

PHP 通过 URL 发送加密数据

linux - 权限被拒绝(公钥)但公钥存在于本地和远程

java - 使用 SonarQube Ant 任务进行分析

ios - 使用 EXIF 数据的 Swift base64 图像编码

c++ - 来自终端的base64编码字符串?

java - sun.security.rsa.RSAPublicKeyImpl 的开源替代品

c# - 使用 WinSCP 禁止在 SFTP 或 SCP 中使用主机 key

java - JSON 与 pretty-print

java - 无法自动连线字段: private org. springframework.security.core.userdetails.UserDetailsS​​ervice

java - 为什么当 if 参数在 java 中已经设置为 true 时, if 的 else case 不会产生任何错误