如何从 base64 编码的字符串构造 java.security.PublicKey 对象?

Posted

技术标签:

【中文标题】如何从 base64 编码的字符串构造 java.security.PublicKey 对象?【英文标题】:How can I construct a java.security.PublicKey object from a base64 encoded string? 【发布时间】:2012-06-09 16:01:27 【问题描述】:

我有一个来自外部源(android 商店)的 bse64 编码字符串公钥,我需要使用它来验证签名内容。如何将字符串转换为 java.security.PublicKey 接口的实例。如果这有所作为,我正在使用 Java 6。

密钥(可能)是使用标准 java 库生成的,而不是充气城堡(它来自远程团队,所以我不确定)。他们的示例代码说要使用 Security.generatePublicKey(base64EncodedPublicKey);但是标准java中的Security对象没有这样的方法。

【问题讨论】:

你用什么来创建你的密钥,标准的 java 库,BouncyCastle 还是别的什么? 很可能是标准 java,但它是一个远程团队,所以我不确定 【参考方案1】:

上述答案的代码

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

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

    return null;

【讨论】:

我使用了类似的代码,但这样更好;)另外,如果在 android 上工作,您可以使用: byte[] byteKey = Base64.decode(key.getBytes(), Base64.DEFAULT ); @Hooli:它是“android.util.Base64”。无论如何,DEFAULT 的值为 0。 显然,你可以从 java.util 中获取 Base64.getDecoder().decode(bytes) 方法。 我像这样修改了第一行以使其在 Java 8 byte[] byteKey = Base64.getDecoder().decode(key.getBytes()); 中工作【参考方案2】:

好笑……试试这个

base64对关键数据进行解码得到字节数组(byte[]) 使用字节数组创建一个新的 X509EncodedKeySpec 在这里假设 RSA 使用 KeyFactory.getInstance("RSA") 获取 KeyFactory 的实例 使用 X509EncodedKeySpec 调用方法 generatePublic(KeySpec) 结果/应该/是供您使用的公钥。

【讨论】:

有同样的问题,试过这个并得到这个异常java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format 我得到了同样的例外。我尝试删除“BEGIN and END CERTIFICATE”,但仍然出现相同的错误。 由于这解决了请求者的情况,请在***上提出一个新问题并在此处提供链接。请提供您正在做什么的代码示例并使用示例证书,例如fm4dd.com/openssl/source/PEM/certs/2048b-rsa-example-cert.pem。理想情况下,注册一个 github 帐户并提供包含您的示例代码和测试证书的存储库的链接。【参考方案3】:

试试这个....

PublicKey getPublicKey(byte[] encodedKey) throws NoSuchAlgorithmException, InvalidKeySpecException

    KeyFactory factory = KeyFactory.getInstance("RSA");
    X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(encodedKey);
    return factory.generatePublic(encodedKeySpec);

【讨论】:

【参考方案4】:

使用海绵城堡

public static PublicKey getPublicKeyFromString(String key) throws Exception 
    KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
    org.spongycastle.asn1.pkcs.RSAPublicKey pkcs1PublicKey
            = org.spongycastle.asn1.pkcs.RSAPublicKey.getInstance(decodeB64(key));
    RSAPublicKeySpec keySpec
            = new RSAPublicKeySpec(pkcs1PublicKey.getModulus(), pkcs1PublicKey.getPublicExponent());
    PublicKey publicKey = keyFactory.generatePublic(keySpec);
    return publicKey;

【讨论】:

【参考方案5】:

你可以试试这个解决方案:

添加这个依赖:

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.61</version>

并使用此方法:

private Key parsePublicKey(String publicKey) throws IOException 
    PEMParser pemParser = new PEMParser(new StringReader(publicKey));
    JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
    SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(pemParser.readObject());
    return converter.getPublicKey(publicKeyInfo);

【讨论】:

【参考方案6】:

这是一个代码sn-p:

import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;

import org.apache.commons.codec.binary.Base64;
try 
    KeyFactory kf = KeyFactory.getInstance("RSA");
    BigInteger modulus = new BigInteger(1, Base64.decodeBase64(this.stringValue("n")));
    BigInteger exponent = new BigInteger(1, Base64.decodeBase64(this.stringValue("e")));
    return kf.generatePublic(new RSAPublicKeySpec(modulus, exponent));
 catch (InvalidKeySpecException var4) 
    throw new InvalidPublicKeyException("Invalid public key", var4);
 catch (NoSuchAlgorithmException var5) 
    throw new InvalidPublicKeyException("Invalid algorithm to generate key", var5);

【讨论】:

以上是关于如何从 base64 编码的字符串构造 java.security.PublicKey 对象?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ios 中将 Base64 编码的 NSString 转换为字节数组(Java)?

如何从 base 64 编码字符串中获取十六进制块?

在 Java 中如何进行 BASE64 编码和解码

如何从 C++ 中的 Base64 编码字符串在 GDI+ 中创建图像?

如何使用 PHP 从 base64 编码的数据/字符串创建图像并将其保存到网站文件夹

从 Base64 编码的字符串中检索 MIME 类型