将Base64编码的CER文件保存为String

时间:2014-08-21 12:48:53

标签: java certificate rsa word-wrap

我目前能够使用此代码从cer文件读取密钥模数,也可以在StackOverflow上找到:

X509Certificate cert = null;
String source = "src/testCer.cer";
InputStream fis = null;                 
ByteArrayInputStream bais = null;               


fis = new FileInputStream(source);              
byte value[] = new byte[fis.available()];       
fis.read(value);                                
bais = new ByteArrayInputStream(value);             
java.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance("X.509");
cert = (X509Certificate)cf.generateCertificate(bais);    
RSAPublicKey pub = (RSAPublicKey) cert.getPublicKey();

System.out.println(pub.getModulus());

.cer文件如下所示:(证书是在互联网上找到的Alice证书示例):

-----BEGIN CERTIFICATE-----
MIIBuTCCASKgAwIBAgIQNdNhtuV5GbNHYZsf+LvM0zANBgkqhkiG9w0BAQUFADAb
MRkwFwYDVQQDExBFZGlkZXYgU21va2VUZXN0MB4XDTA4MTExMjE5NTEzNVoXDTM5
MTIzMTIzNTk1OVowGzEZMBcGA1UEAxMQRWRpZGV2IFNtb2tlVGVzdDCBnzANBgkq
hkiG9w0BAQEFAAOBjQAwgYkCgYEAm6zGzqxejwswWTNLcSsa7P8xqODspX9VQBuq
5W1RoTgQ0LNR64+7ywLjH8+wrb/lB6QV7s2SFUiWDeduVesvMJkWtZ5zzQyl3iUa
CBpT4S5AaO3/wkYQSKdI108pXH7Aue0e/ZOwgEEX1N6OaPQn7AmAB4uq1h+ffw+r
RKNHqnsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCZmj+pgRsN6HpoICawK3XXNAmi
cgfQkailX9akIjD3xSCwEQx4nG6tZjTz30u4NoSffW7pch58SxuZQDqW5NsJcQNq
Ngo/dMoqqpXdi2/0BYEcJ8pjsngrFm+fM2BnyGpXH7aWuKsWjVFGlWlF+yi8I35Q
8wFJt2Z/XGA7WWDjvw==
-----END CERTIFICATE-----

一个很好的Base64编码包装文本。

我的问题:

如何将此证书保存到字符串,并使用该证书而不是从文件中读取证书?

到目前为止,我试过了:

String cert_1= "-----BEGIN CERTIFICATE-----"
                + "MIIBuTCCASKgAwIBAgIQNdNhtuV5GbNHYZsf+LvM0zANBgkqhkiG9w0BAQUFADAb"
                + "MRkwFwYDVQQDExBFZGlkZXYgU21va2VUZXN0MB4XDTA4MTExMjE5NTEzNVoXDTM5"
                + "MTIzMTIzNTk1OVowGzEZMBcGA1UEAxMQRWRpZGV2IFNtb2tlVGVzdDCBnzANBgkq"
                + "hkiG9w0BAQEFAAOBjQAwgYkCgYEAm6zGzqxejwswWTNLcSsa7P8xqODspX9VQBuq"
                + "CBpT4S5AaO3/wkYQSKdI108pXH7Aue0e/ZOwgEEX1N6OaPQn7AmAB4uq1h+ffw+r"
                + "5W1RoTgQ0LNR64+7ywLjH8+wrb/lB6QV7s2SFUiWDeduVesvMJkWtZ5zzQyl3iUa"
                + "RKNHqnsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCZmj+pgRsN6HpoICawK3XXNAmi"
                + "cgfQkailX9akIjD3xSCwEQx4nG6tZjTz30u4NoSffW7pch58SxuZQDqW5NsJcQNq"
                + "Ngo/dMoqqpXdi2/0BYEcJ8pjsngrFm+fM2BnyGpXH7aWuKsWjVFGlWlF+yi8I35Q"
                + "8wFJt2Z/XGA7WWDjvw=="
                + "-----END CERTIFICATE-----";

    fis = new ByteArrayInputStream(cert_1.getBytes());

导致错误: java.io.IOException:数据不完整

fis.available也与从文件加载的证书不同。 (它短2)。 我猜这与包裹有关。我怀疑这是因为如果在记事本中看到第一行上没有单独的Header,则.cer文件不起作用,但确实有效。

1 个答案:

答案 0 :(得分:2)

问题是你的字符串文字没有任何换行符。要忠实地代表原始文本,您需要:

String cert_1= "-----BEGIN CERTIFICATE-----\n"
    + "MIIBuTCCASKgAwIBAgIQNdNhtuV5GbNHYZsf+LvM0zANBgkqhkiG9w0BAQUFADAb\n"
    + "MRkwFwYDVQQDExBFZGlkZXYgU21va2VUZXN0MB4XDTA4MTExMjE5NTEzNVoXDTM5\n"
    + "MTIzMTIzNTk1OVowGzEZMBcGA1UEAxMQRWRpZGV2IFNtb2tlVGVzdDCBnzANBgkq\n"
    + "hkiG9w0BAQEFAAOBjQAwgYkCgYEAm6zGzqxejwswWTNLcSsa7P8xqODspX9VQBuq\n"
    + "CBpT4S5AaO3/wkYQSKdI108pXH7Aue0e/ZOwgEEX1N6OaPQn7AmAB4uq1h+ffw+r\n"
    + "5W1RoTgQ0LNR64+7ywLjH8+wrb/lB6QV7s2SFUiWDeduVesvMJkWtZ5zzQyl3iUa\n"
    + "RKNHqnsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCZmj+pgRsN6HpoICawK3XXNAmi\n"
    + "cgfQkailX9akIjD3xSCwEQx4nG6tZjTz30u4NoSffW7pch58SxuZQDqW5NsJcQNq\n"
    + "Ngo/dMoqqpXdi2/0BYEcJ8pjsngrFm+fM2BnyGpXH7aWuKsWjVFGlWlF+yi8I35Q\n"
    + "8wFJt2Z/XGA7WWDjvw==\n"
    + "-----END CERTIFICATE-----";

...但你可能只是确保BEGIN CERTIFICATEEND CERTIFICATE标记在他们自己的行上,这样你就可以逃脱:

String cert_1= "-----BEGIN CERTIFICATE-----\n"
    + "MIIBuTCCASKgAwIBAgIQNdNhtuV5GbNHYZsf+LvM0zANBgkqhkiG9w0BAQUFADAb"
    + "MRkwFwYDVQQDExBFZGlkZXYgU21va2VUZXN0MB4XDTA4MTExMjE5NTEzNVoXDTM5"
    + "MTIzMTIzNTk1OVowGzEZMBcGA1UEAxMQRWRpZGV2IFNtb2tlVGVzdDCBnzANBgkq"
    + "hkiG9w0BAQEFAAOBjQAwgYkCgYEAm6zGzqxejwswWTNLcSsa7P8xqODspX9VQBuq"
    + "CBpT4S5AaO3/wkYQSKdI108pXH7Aue0e/ZOwgEEX1N6OaPQn7AmAB4uq1h+ffw+r"
    + "5W1RoTgQ0LNR64+7ywLjH8+wrb/lB6QV7s2SFUiWDeduVesvMJkWtZ5zzQyl3iUa"
    + "RKNHqnsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQCZmj+pgRsN6HpoICawK3XXNAmi"
    + "cgfQkailX9akIjD3xSCwEQx4nG6tZjTz30u4NoSffW7pch58SxuZQDqW5NsJcQNq"
    + "Ngo/dMoqqpXdi2/0BYEcJ8pjsngrFm+fM2BnyGpXH7aWuKsWjVFGlWlF+yi8I35Q"
    + "8wFJt2Z/XGA7WWDjvw==\n"
    + "-----END CERTIFICATE-----";

我还建议您在文本和二进制数据之间进行转换时明确指定字符集:

fis = new ByteArrayInputStream(cert_1.getBytes(StandardCharsets.UTF_8));