使用PemReader和Openssl进行私钥解析

时间:2018-01-31 22:10:56

标签: 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: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

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA2lKPRVgFN8TfOhex+IJ6YMKUKeZgHZUGsJpHo/ipeYVeWUGa
jKVANloG3IX/I5Zo8FZ6R6BVCEisaGqH35HwktZ+vdrGzuRNGUERnZiy1nXzKDmV
CGdBY/PxErvvEyygHPd8X9HNGagjOlKLrPGyN2dAp6sMpljNevSzbXYxCX0KOm9z
ox40c2qdXFqa26mUWKVVZ6TdYSIeV1s/n3oRvAA3fbFAdTg4xM++g/V8LXyipDK4
gEqNPwJzzvE6u0P0u+MFCEgogbVZLVelLq6OzTU27pigwourVAf8eWyRYX8TOz2E
A1HDDKy7dSwTaIz7TPXfYqwe+bwLEl5vX/dQ6QIDAQABAoIBADBPcJChp5XtpI/Q
Snt5M+dRZ0PWTJJ/NZnCqfOoxKe1UWli0PYqYwkj5rzJkemoENSN7kUHP4mzuyLn
3+UjAB8eA7GzRabmcgESmvlKnthCBWpzQ302jAu4ITJKD98oUs3WHdl+LWpuAE2Z
knrUiOElofL4MLZmlCGPIF0qeDNm5QkLanMyzu7bduo8etwn2NNBHxDdc4eW2c2l
d4m1INObx4ZyAkoBWksKN8PsDH2I3FZJFvkgve1fFhff0U+CtertfOwlFoAmDv9j
FtJq2Y6H2p+Q1eyRlh0OLAK7qZ5MhgBOMe3PNxeJWa3S4Z/gevihweclmK/F9e9T
/V5JVgECgYEA/W6eKy2cgkajjgBPu4tsW8XTo9lyWnWLYUY2PacgfhT7zkZy4s4g
cfP1zjjGXZaDYgo7MPoBM0xFLYbrWQ7j8GgA18uTHZs2yjYya1a6iyi8RMdQpRzd
jzCDfHNeJ2YU1apVuqs8r99sskkg/S2gd31XCuKwYTgCVgi4GmczUiECgYEA3Ije
0F/Ojb7dV35w0K+NK6rl/RL42cDcy5qjEAlI5zUcbxubjy+gHwCBM6dwx8frIeaX
BG512loqoALKXvLzSUAWbnPsvkQCOkcBPvi48tkWh3h1QO1S1U38KrWr58+9WCLs
5tL14l8O8JQmNg/0jLA4k3OHhL/gy6VQGolLNckCgYB5T9kgnA2+AqhJ0fZYtO2i
pHihhvYJPRkB8EUIkBaqo8rBO9HEpZy8T2ZLV7wEkobDiFg7IoEumATJPTss/0a3
DmHQ6l66nlDEzNqnrPVQpagxWCNPVhjscPGPwf3A6Ely2b19xHghS9bRJNZIuu2E
JRhkWozJjLD5k+Tkpp/XYQKBgDiv/gY1+lQ5MZAh8kHSPklxPnkU/V6L0rWLZErk
+BZmco6k3BGsPk55xLxQWA8idnBaY4tCEY01DCvhS7+oV50Gmj1+Eua9eI0eX1We
fXv/DWl5LzqnRlmKGD2qQSvvHE6he5/Brm6n3KE+k6vl4gif64sLcVRQNipirfqE
PA7xAoGBAJ8wfxLaj86/f+JU2jAd34HYZpNQ1mEb2TqZkrLqk78VXaKhyZjw2IGe
Pt5ROLZNIQbVWcTSMD2TrDsZGDY5zq5hXnRXb2h1Q1PHbbixl0s3TnDZ0JGxxrLQ
iAc48q1o36aAYVSyY/JLR3Q9Su97+i55Ud5rDYW5ThLcACsjxB/mL
-----END RSA PRIVATE KEY-----

提前致谢 尼古拉

2 个答案:

答案 0 :(得分:0)

  

我的期望是有一个例外,你有什么想法吗?这是我的验证错了吗?

密钥格式错误。首先,保存PEM编码密钥:

echo '-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA2lKPRVgFN8TfOhex+IJ6YMKUKeZgHZUGsJpHo/ipeYVeWUGa
...
iAc48q1o36aAYVSyY/JLR3Q9Su97+i55Ud5rDYW5ThLcACsjxB/mL
-----END RSA PRIVATE KEY-----' > key.pem

其次,将其转换为DER。这将剥离第一行和最后一行,然后base64对其进行解码:

sed '$d' < key.pem | sed "1d" | openssl base64 -d > key.der

第三,用另一种工具检查密钥:

$ dumpasn1 key.der
   0 1187: SEQUENCE {
   4    1:   INTEGER 0
   7  257:   INTEGER
         :     00 DA 52 8F 45 58 05 37 C4 DF 3A 17 B1 F8 82 7A
         :     60 C2 94 29 E6 60 1D 95 06 B0 9A 47 A3 F8 A9 79
         :     85 5E 59 41 9A 8C A5 40 36 5A 06 DC 85 FF 23 96
         :     68 F0 56 7A 47 A0 55 08 48 AC 68 6A 87 DF 91 F0
         :     92 D6 7E BD DA C6 CE E4 4D 19 41 11 9D 98 B2 D6
         :     75 F3 28 39 95 08 67 41 63 F3 F1 12 BB EF 13 2C
         :     A0 1C F7 7C 5F D1 CD 19 A8 23 3A 52 8B AC F1 B2
         :     37 67 40 A7 AB 0C A6 58 CD 7A F4 B3 6D 76 31 09
         :             [ Another 129 bytes skipped ]
 268    3:   INTEGER 65537
 273  256:   INTEGER
         :     30 4F 70 90 A1 A7 95 ED A4 8F D0 4A 7B 79 33 E7
         :     51 67 43 D6 4C 92 7F 35 99 C2 A9 F3 A8 C4 A7 B5
         :     51 69 62 D0 F6 2A 63 09 23 E6 BC C9 91 E9 A8 10
         :     D4 8D EE 45 07 3F 89 B3 BB 22 E7 DF E5 23 00 1F
         :     1E 03 B1 B3 45 A6 E6 72 01 12 9A F9 4A 9E D8 42
         :     05 6A 73 43 7D 36 8C 0B B8 21 32 4A 0F DF 28 52
         :     CD D6 1D D9 7E 2D 6A 6E 00 4D 99 92 7A D4 88 E1
         :     25 A1 F2 F8 30 B6 66 94 21 8F 20 5D 2A 78 33 66
         :             [ Another 128 bytes skipped ]
 533  129:   INTEGER
         :     00 FD 6E 9E 2B 2D 9C 82 46 A3 8E 00 4F BB 8B 6C
         :     5B C5 D3 A3 D9 72 5A 75 8B 61 46 36 3D A7 20 7E
         :     14 FB CE 46 72 E2 CE 20 71 F3 F5 CE 38 C6 5D 96
         :     83 62 0A 3B 30 FA 01 33 4C 45 2D 86 EB 59 0E E3
         :     F0 68 00 D7 CB 93 1D 9B 36 CA 36 32 6B 56 BA 8B
         :     28 BC 44 C7 50 A5 1C DD 8F 30 83 7C 73 5E 27 66
         :     14 D5 AA 55 BA AB 3C AF DF 6C B2 49 20 FD 2D A0
         :     77 7D 57 0A E2 B0 61 38 02 56 08 B8 1A 67 33 52
         :     21
 665  129:   INTEGER
         :     00 DC 88 DE D0 5F CE 8D BE DD 57 7E 70 D0 AF 8D
         :     2B AA E5 FD 12 F8 D9 C0 DC CB 9A A3 10 09 48 E7
         :     35 1C 6F 1B 9B 8F 2F A0 1F 00 81 33 A7 70 C7 C7
         :     EB 21 E6 97 04 6E 75 DA 5A 2A A0 02 CA 5E F2 F3
         :     49 40 16 6E 73 EC BE 44 02 3A 47 01 3E F8 B8 F2
         :     D9 16 87 78 75 40 ED 52 D5 4D FC 2A B5 AB E7 CF
         :     BD 58 22 EC E6 D2 F5 E2 5F 0E F0 94 26 36 0F F4
         :     8C B0 38 93 73 87 84 BF E0 CB A5 50 1A 89 4B 35
         :     C9
 797  128:   INTEGER
         :     79 4F D9 20 9C 0D BE 02 A8 49 D1 F6 58 B4 ED A2
         :     A4 78 A1 86 F6 09 3D 19 01 F0 45 08 90 16 AA A3
         :     CA C1 3B D1 C4 A5 9C BC 4F 66 4B 57 BC 04 92 86
         :     C3 88 58 3B 22 81 2E 98 04 C9 3D 3B 2C FF 46 B7
         :     0E 61 D0 EA 5E BA 9E 50 C4 CC DA A7 AC F5 50 A5
         :     A8 31 58 23 4F 56 18 EC 70 F1 8F C1 FD C0 E8 49
         :     72 D9 BD 7D C4 78 21 4B D6 D1 24 D6 48 BA ED 84
         :     25 18 64 5A 8C C9 8C B0 F9 93 E4 E4 A6 9F D7 61
 928  128:   INTEGER
         :     38 AF FE 06 35 FA 54 39 31 90 21 F2 41 D2 3E 49
         :     71 3E 79 14 FD 5E 8B D2 B5 8B 64 4A E4 F8 16 66
         :     72 8E A4 DC 11 AC 3E 4E 79 C4 BC 50 58 0F 22 76
         :     70 5A 63 8B 42 11 8D 35 0C 2B E1 4B BF A8 57 9D
         :     06 9A 3D 7E 12 E6 BD 78 8D 1E 5F 55 9E 7D 7B FF
         :     0D 69 79 2F 3A A7 46 59 8A 18 3D AA 41 2B EF 1C
         :     4E A1 7B 9F C1 AE 6E A7 DC A1 3E 93 AB E5 E2 08
         :     9F EB 8B 0B 71 54 50 36 2A 62 AD FA 84 3C 0E F1
1059  129:   INTEGER
         :     00 9F 30 7F 12 DA 8F CE BF 7F E2 54 DA 30 1D DF
         :     81 D8 66 93 50 D6 61 1B D9 3A 99 92 B2 EA 93 BF
         :     15 5D A2 A1 C9 98 F0 D8 81 9E 3E DE 51 38 B6 4D
         :     21 06 D5 59 C4 D2 30 3D 93 AC 3B 19 18 36 39 CE
         :     AE 61 5E 74 57 6F 68 75 43 53 C7 6D B8 B1 97 4B
         :     37 4E 70 D9 D0 91 B1 C6 B2 D0
         :     Error: Unexpected EOF, 39 bytes missing.
Error: Inconsistent object length, 39 bytes difference.
         :   }
Error: Inconsistent object length, 38 bytes difference.

0 warnings, 3 errors.

当您查看从字节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

答案 1 :(得分:0)

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