当前位置: 首页 > 面试题库 >

从PEM BASE64编码的私钥文件中获取RSA私钥

上官正志
2023-03-14
问题内容

我有一个私钥文件(PEM BASE64编码)。我想在其他地方使用它解密其他数据。使用Java,我尝试读取文件并解码其中的BASE64编码数据。这是我尝试的代码段。

import java.io.;
import java.nio.ByteBuffer;
import java.security.

;
import java.security.spec.PKCS8EncodedKeySpec;
import com.ibm.crypto.fips.provider.RSAPrivateKey;
import com.ibm.misc.BASE64Decoder;

public class GetPrivateKey {
public static RSAPrivateKey get() throws Exception {
File privateKeyFile = new File(“privatekey.key”);
byte[] encodedKey = new byte[(int) privateKeyFile.length()];
new FileInputStream(privateKeyFile).read(encodedKey);
ByteBuffer keyBytes = new BASE64Decoder().decodeBufferToByteBuffer(encodedKey.toString());
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytes.array());
KeyFactory kf = KeyFactory.getInstance(“RSA”, “IBMJCEFIPS”);
RSAPrivateKey pk = (RSAPrivateKey) kf.generatePrivate(privateKeySpec);
return pk;
}

public static void main(String[] args) throws Exception {
    PrivateKey privKey = FormatMePlease.get();
    System.out.println(privKey.toString());
}

}
我收到以下错误

Exception in thread “main” java.security.spec.InvalidKeySpecException: Inappropriate key specification: DerInputStream.getLength(): lengthTag=127, too big.
at com.ibm.crypto.fips.provider.RSAKeyFactory.b(Unknown Source)
at com.ibm.crypto.fips.provider.RSAKeyFactory.engineGeneratePrivate(Unknown Source)
at java.security.KeyFactory.generatePrivate(Unknown Source)
at GetPrivateKey.get(GetPrivateKey.java:24)
at GetPrivateKey.main(GetPrivateKey.java:29)
文件“ privatekey.key”的内容

-----BEGIN RSA PRIVATE KEY-----
MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAF53wUbKmDHtvfOb8u1HPqEBFNNF
csnOMjIcSEhAwIQMbgrOuQ+vH/YgXuuDJaURS85H8P4UTt6lYOJn+SFnXvS82E7LHJpVrWwQzbh2
QKh13/akPe90DlNTUGEYO7rHaPLqTlld0jkLFSytwqfwqn9yrYpM1ncUOpCciK5j8t8MzO71LJoJ
g24CFxpjIS0tBrJvKzrRNcxWSRDLmu2kNmtsh7yyJouE6XoizVmBmNVltHhFaDMmqjugMQA2CZfL
rxiR1ep8TH8IBvPqysqZI1RIpB/e0engP4/1KLrOt+6gGS0JEDh1kG2fJObl+N4n3sCOtgaz5Uz8
8jpwbmZ3Se8CAwEAAQKCAQAdOsSs2MbavAsIM3qo/GBehO0iqdxooMpbQvECmjZ3JTlvUqNkPPWQ
vFdiW8PsHTvtackhdLsqnNUreKxXL5rr8vqi9qm0/0mXpGNi7gP3m/FeaVdYnfpIwgCe6lag5k6M
yv7PG/6N8+XrWyBdwlOe96bGohvB4Jp2YFjSTM67QONQ8CdmfqokqJ8/3RyrpDvGN3iX3yzBqXGO
jPkoJQv3I4lsYdR0nl4obHHnMSeWCQCYvJoZ7ZOliu/Dd0ksItlodG6s8r/ujkSa8VIhe0fnXTf0
i7lqa55CAByGN4MOR0bAkJwIB7nZzQKurBPcTAYJFFvAc5hgMnWT0XW83TehAoGBALVPGnznScUw
O50OXKI5yhxGf/XDT8g28L8Oc4bctRzI+8YfIFfLJ57uDGuojO/BpqtYmXmgORru0jYR8idEkZrx
gf62czOiJrCWTkBCEMtrNfFHQJQCQrjfbHofp7ODnEHbHFm7zdlbfNnEBBaKXxd2rVv4UTEhgftv
wsHcimbXAoGBAIViWrHWElMeQT0datqlThE/u51mcK4VlV7iRWXVa1/gAP85ZAu44VvvDlkpYVkF
zSRR+lHSOzsubDMN45OBQW6UA3RPg4TCvrTOmhQUeF5XPuSdcD0R2At6pdaLwAKnOtILg13Ha6ym
Igjv8glodvem3hWLmpHIhNBiaXtf8wqpAoGADH5a8OhvKOtd8EChGXyp9LDW+HRw9vbyN/gi9dQX
ltgyoUBb1jDllgoJSRHgRFUvyvbb/ImR5c03JwqtiQ8siWTC9G5WGeS+jcSNt9fVmG7W1L14MbrG
Jj8fFns/7xrOlasnlPdgA+5N+CONtI/sZY2D/KZr0drhPhZBcWJlFxkCgYAn+4SOPEo/6hjKNhA6
vER7fSxDEVsDg+rDh3YgAWpvUdlaqBxqOyAqi600YugQZGHK2lv7vNYOdmrunuIx7BPuDqY+bjtR
R4Mc9bVQAZbXSLXMl7j2RWwKfNhLSJbk9LX4EoVtTgLjvOUE4tAdq9fFgpqdwLwzqPTO9kECP4++
CQKBgH6tO/xcNxG/uXUideluAn3H2KeyyznZMJ7oCvzf26/XpTAMI243OoeftiKVMgxuZ7hjwqfn
/VHXABc4i5gchr9RzSb1hZ/IqFzq2YGmbppg5Ok2cgwalDoDBi21bRf8aDRweL62mO+7aPnCQZ58
j5W72PB8BAr6xg0Oro25O4os
-----END RSA PRIVATE KEY-----
类似的问题已经在这里发布,但对我而言这些都无济于事。几乎所有人都建议使用Bouncycastle提供程序,该提供程序不愿意使用应该使用的FIPS兼容提供程序,并且不确定BC提供程序是否符合FIPS。

非常感谢您提供帮助,…谢谢。


问题答案:

由于缺少ASN1支持,因此解析PKCS1(在Android上仅开箱即用的PKCS8格式)键是一项繁琐的任务,但如果包含Spongy castle jar以读取DER Integers,则可以解决。

String privKeyPEM = key.replace(
"-----BEGIN RSA PRIVATE KEY-----\n", "")
    .replace("-----END RSA PRIVATE KEY-----", "");

// Base64 decode the data

byte[] encodedPrivateKey = Base64.decode(privKeyPEM, Base64.DEFAULT);

try {
    ASN1Sequence primitive = (ASN1Sequence) ASN1Sequence
        .fromByteArray(encodedPrivateKey);
    Enumeration<?> e = primitive.getObjects();
    BigInteger v = ((DERInteger) e.nextElement()).getValue();

    int version = v.intValue();
    if (version != 0 && version != 1) {
        throw new IllegalArgumentException("wrong version for RSA private key");
    }
    /**
     * In fact only modulus and private exponent are in use.
     */
    BigInteger modulus = ((DERInteger) e.nextElement()).getValue();
    BigInteger publicExponent = ((DERInteger) e.nextElement()).getValue();
    BigInteger privateExponent = ((DERInteger) e.nextElement()).getValue();
    BigInteger prime1 = ((DERInteger) e.nextElement()).getValue();
    BigInteger prime2 = ((DERInteger) e.nextElement()).getValue();
    BigInteger exponent1 = ((DERInteger) e.nextElement()).getValue();
    BigInteger exponent2 = ((DERInteger) e.nextElement()).getValue();
    BigInteger coefficient = ((DERInteger) e.nextElement()).getValue();

    RSAPrivateKeySpec spec = new RSAPrivateKeySpec(modulus, privateExponent);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PrivateKey pk = kf.generatePrivate(spec);
} catch (IOException e2) {
    throw new IllegalStateException();
} catch (NoSuchAlgorithmException e) {
    throw new IllegalStateException(e);
} catch (InvalidKeySpecException e) {
    throw new IllegalStateException(e);
}


 类似资料:
  • 我有一个私钥文件(PEM BASE64编码)。我想用它来解密一些其他数据。使用Java我试着读取文件并解码其中的BASE64编码数据。这是我尝试的代码片段.... 我得到以下错误 类似的问题已经贴在这里,但那些对我没有用。几乎所有的人都建议使用Bouncycastle provider,而Bouncycastle provider并不愿意使用FIPS兼容的provider,并且不确定BC prov

  • 问题内容: 给定此文件(使用openssl生成并使用密码加密): 如何使用Java 获取对象?我编写了以下代码,但是找不到正确的方法来获取: 我想我应该构建一个,但我不知道如何。我尝试了这个答案和另一个答案中的方法,但是它们在解析字节数组时都导致错误。 问题答案: 我正在使用 BouncyCastle 1.57 (bcprov-jdk15on,bcmail-jdk15on和bcpkix-jdk15

  • 给定这个文件(使用openssl生成并使用密码加密): 如何在Java中获得一个< code>PrivateKey对象?我编写了以下代码,但是我找不到获取< code>KeySpec的正确方法: 我想我应该构建一个<code>RSAPrivateKeySpec</code>,但我不知道怎么做。我尝试了这个答案和另一个答案中的方法,但在解析字节数组时,它们都会导致错误。

  • (我正在用MAC) 我的id_rsa以 但我希望一开始 我已将我的身份证发送给rsa。发布给服务器管理员以获得对服务器的访问权,因此我不想生成新密钥。 > 有什么方法可以将我的id_rsaopenssh私钥转移到RSA私钥吗?(请指挥。) 如果我可以传输,我是否还需要传输id_rsa。酒吧(请发命令。)看来是我的错。pub没有像id_rsa这样的头,所以我不确定是否也应该传输它。 非常感谢。

  • 问题内容: 我正在为SAML 1.1断言消费者服务开发测试工具。测试必须生成签名的SAMLResponse,并将其提交给以Base64编码的ACS。ACS必须能够使用X509公共证书来验证签名的消息。 我能够构建SAMLResponse,添加必要的断言等。但是,当我尝试对对象进行签名时,我遇到了问题。这是我当前代码的一个片段: 错误发生在倒数第二行。我在控制台中看到以下内容: 尽管不是常规或安全的

  • 问题内容: 我正在尝试从java中的文件加载私钥。该密钥由ssh-agent生成。我实际上正在使用以下代码: 但是它产生了这个异常: 这是私钥: 有什么建议?谢谢。 问题答案: 您确定它是RSA吗?您还确定密钥的格式正确吗? 如果两个问题的答案都是肯定的,则可以尝试使用bouncycastle lib 编辑: 尝试从密钥中删除这些行: 更新:请 确保您的私钥为PKCS8格式,如果不需要,请按此处进