Java 使用PemReader和Openssl进行私钥解析

Java 使用PemReader和Openssl进行私钥解析,java,security,bouncycastle,private-key,pem,Java,Security,Bouncycastle,Private Key,Pem,我为HTTPS代理编写了一个配置系统。在推送配置文件和上载证书和私钥之前,我会进行一些验证。我发现Java使用PemReader OpenSSL验证私钥时,不会验证同一个文件。这会导致httpd服务器停止工作,因为它获取了错误的密钥 我做了一个测试来复制它: 使用openssl我有一个错误 $ openssl rsa -in wrong_key_test.key -check unable to load Private Key 140736227525512:error:0906D064:PE

我为HTTPS代理编写了一个配置系统。在推送配置文件和上载证书和私钥之前,我会进行一些验证。我发现Java使用PemReader OpenSSL验证私钥时,不会验证同一个文件。这会导致httpd服务器停止工作,因为它获取了错误的密钥

我做了一个测试来复制它:

使用openssl我有一个错误

$ openssl rsa -in wrong_key_test.key -check
unable to load Private Key
140736227525512:error:0906D064:PEM routines:PEM_read_bio:bad base64 decode:/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-22/libressl/crypto/pem/pem_lib.c:828:
但是当我运行这个junit测试时,一切都正常。我的期望是有一个例外,你知道吗?是我的验证错了吗

这是junit

package eu.ssl.test.validator;
import static org.junit.Assert.assertNotEquals;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.security.KeyFactory;
import java.security.Security;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

import org.apache.commons.io.FileUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;
import org.junit.Before;
import org.junit.Test;

public class PemReaderTest {

private String privateKey;

@Before
public void setUp() throws IOException {
    this.privateKey = FileUtils.readFileToString(new File("./wrong_key_test.key"));
}

@Test
public void test() throws Exception {
    Security.addProvider(new BouncyCastleProvider());
    PemReader pemReader = new PemReader(new StringReader(this.privateKey));
    PemObject pemObject;
    try {
        pemObject = pemReader.readPemObject();
    } finally {
        pemReader.close();
    }
    KeyFactory factory = KeyFactory.getInstance("RSA");
    byte[] content = pemObject.getContent();
    PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(content);
    RSAPrivateKey privateKey = (RSAPrivateKey) factory.generatePrivate(privKeySpec);
    String privateKeyModulus = privateKey.getModulus().toString();
    assertNotEquals("", privateKeyModulus);
}   
}
这就是PK

----开始RSA私钥-----
MIIEowIBAAKCAQEA2lKPRVgFN8TfOhex+IJ6YMKUKeZgHZUGsJpHo/ipeYVeWUGa
jKVANloG3IX/I5ZO8FZ6R6BVCEIAGQH35HWKTZ+vdrGzuRNGUERnZiy1nXzKDmV
CGdBY/PXERVERVEYYGHPD8X9HNGAGJOLKLRPGYN2DAP6SMPLJNEVSZBXYXCx0KOM9Z
ox40c2qdXFqa26mUWKVVZ6TdYSIeV1s/N3或VAA3FBFADTG4XM++g/V8LXyipDK4
gEqNPwJzzvE6u0P0u+MFCEGOGBVZLVELQ6OZTU27PIGWOURVAF8EWYRYX8TOZ2E
A1HDDKy7dSwTaIz7TPXfYqwe+bwLEl5vX/DQ6QIDAQABAOIBABDBPCJCHP5XTPI/Q
Snt5M+dRZ0PWTJJ/NZNCQFOOXKE1UWLI0PYQYWKJ5RZJKEMONENSN7KUHP4MZUYLN
3+UJAB8EA7GZRABMGCESMVLKNTHCBWPZQ302JAU4ITJKD98OUS3WHDL+LWpuAE2Z
KNRUIOELFL4MLZMLCGPIF0QEDNM5QKLANMYZU7BDU8ETWN2NNBHXDDC4EW2C2L
D4M1INOBX4ZYAKOBWKSKN8PSDH2I3FZJFVKGVEF1FF0U+CTERTFOWLFOFMOLAMDV9J
FtJq2Y6H2p+Q1eyRlh0OLAK7qZ5MhgBOMe3PNxeJWa3S4Z/GEVIHWELCMK/F9e9T
/V5JVgECgYEA/W6EKY2CKAJGBPU4TSW8XTO9LYWNWLYYY2PACGFHT7ZKZY4S4G
CFP1ZJGXZADYGO7MPOBM0xFLYBRWQ7J8GGA18UTHZS2YJYYA1A6IYI8RMDQPRZD
JZCDHNEJ2YU1APVUQS8R99SSKKG/S2gd31XCuKwYTgCVgi4GmczUiECgYEA3Ije
0F/Ojb7dV35w0K+NK6rl/RL42cDcy5qjEAlI5zUcbxubjy+gHwCBM6dwx8frIeaX
BG512LOQOALKXVLZSUAWBNPSVKQCOKCBPVI48TKWH3H1QO1S1U38KWR58+9WCLs
5tL14l8O8JQmNg/0jLA4k3OHhL/GY6VQGOLLNCCGYB5T9KGNA2+AqhJ0fZYtO2i
pHihhvYJPRkB8EUIkBaqo8rBO9HEpZy8T2ZLV7wEkobDiFg7IoEumATJPTss/0a3
DMHQ6L66NLDEZNQNRPVQPAGXWCNPVHJSCPGPWF3A6ELY2B19XHGHS9BRJNZIU2E
JRhkWozJjLD5k+Tkpp/XYQKBgDiv/gY1+lQ5MZAh8kHSPklxPnkU/V6L0rWLZErk
+BZMCO6K3BGSPK55XLXQWA8IDNBAY4TCY01DCVHS7+oV50Gmj1+Eua9eI0eX1We
fXv/DWl5LzqnRlmKGD2qQSvvHE6he5/Brm6n3KE+K6VL4GIF64SLCVRQNIPIRFKE
PA7xAoGBAJ8wfxLaj86/f+JU2JAD34YZPNQ1MEB2TQZKRLQK78VXAKYZJW2GE
Pt5ROLZNIQbVWcTSMD2TrDsZGDY5zq5hXnRXb2h1Q1PHbbixl0s3TnDZ0JGxxrLQ
iAc48q1o36aAYVSyY/JLR3Q9Su97+i55Ud5rDYW5ThLcACsjxB/mL
-----结束RSA私钥-----
提前谢谢 尼古拉

我的期望是有一个例外,你知道吗?是我的验证错了吗

密钥格式不正确。首先,保存PEM编码的密钥:

echo'----开始RSA私钥-----
MIIEowIBAAKCAQEA2lKPRVgFN8TfOhex+IJ6YMKUKeZgHZUGsJpHo/ipeYVeWUGa
...
iAc48q1o36aAYVSyY/JLR3Q9Su97+i55Ud5rDYW5ThLcACsjxB/mL
-----结束RSA私钥------'>KEY.pem
第二,将其转换为DER。这将剥离第一行和最后一行,然后base64对其进行解码:

sed '$d' < key.pem | sed "1d" | openssl base64 -d > key.der
当您查看从字节0开始的第一个ASN.1序列时:

0 1187: SEQUENCE
这个序列应该有1187个内容八位组。但这是不可能的,因为文件中只有1152个字节:

$ ls -Al key.pem key.der
-rw-rw-r--. 1 jwalton jwalton 1152 Jan 31 19:49 key.der
-rw-rw-r--. 1 jwalton jwalton 1676 Jan 31 19:41 key.pem

我使用的是spring boot 1.5.3,它使用的是旧的Bouncy Castle版本(bcpkix-jdk15 1.47)。当我运行版本为1.59的测试脚本时,我得到了预期的结果。版本1.58或更低版本似乎无法识别此格式错误的密钥。

正在测试的私钥的来源是什么?当我在私钥上运行代码时,它会从行
RSAPrivateKey privateKey=(RSAPrivateKey)工厂引发异常。generatePrivate(privKeySpec)