如何在Java中读取sha1WithRSAEncryption公共DER密钥?

时间:2015-11-13 16:00:47

标签: java cryptography

openssl x509 -inform DER -text 
我的DER文件上的

在这个问题的底部给出了转储。

我尝试用以下内容阅读:

static PublicKey getCertKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
    URL keyUrl = Resources.getResource(LManager.class, "iid.der");
    byte[] keyBytes = Resources.toByteArray(keyUrl);
    X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePublic(spec);
}

我得到了:

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
....
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at Caused by: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
at sun.security.x509.X509Key.decode(X509Key.java:397)
at sun.security.x509.X509Key.decode(X509Key.java:403)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:83)
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)
... 25 more


Certificate:
Data:
    Version: 3 (0x2)
    Serial Number:
        a9:cb:e1:41:03:30:df:c5
    Signature Algorithm: sha1WithRSAEncryption
    Issuer: REDACTED
    Validity
        Not Before: Jun  5 14:28:02 2014 GMT
        Not After : Jun  5 14:28:02 2024 GMT
    Subject: REDACTED
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
        RSA Public Key: (1024 bit)
            Modulus (1024 bit):
                00:87:bd:18:df:ff:49:12:b6:92:76:e3:c9:21:b4:
                86:8d:f2:a9:03:37:7b:64:c3:85:63:bc:0f:67:bc:
                f9:76:6a:72:4e:f9:e2:01:52:a3:df:40:6d:3d:91:
                99:70:a5:6a:66:c8:ef:1b:18:1d:91:5a:a5:b1:0b:
                0b:81:fd:d7:27:22:86:fa:c3:8d:b4:93:d5:98:e4:
                2d:08:20:6b:43:44:d6:ae:37:79:2e:bc:65:e4:c3:
                71:c4:9c:5d:04:8d:8a:f4:a5:cc:96:52:f0:72:59:
                8e:0a:b3:06:55:e3:65:fb:63:b5:d2:4b:5d:e1:38:
                87:0b:e8:d2:c0:f8:7f:78:fd
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Subject Key Identifier:
            25:D6:CC:08:15:CA:B6:F0:9C:59:DC:14:52:2C:EF:B5:41:76:51:38
        X509v3 Authority Key Identifier:
            keyid:25:D6:CC:08:15:CA:B6:F0:9C:59:DC:14:52:2C:EF:B5:41:76:51:38
            DirName:/C=US/ST=Washington/L=Seattle/O=Amazon.com Inc./CN=ec2.amazonaws.com
            serial:A9:CB:E1:41:03:30:DF:C5

        X509v3 Basic Constraints:
            CA:TRUE

1 个答案:

答案 0 :(得分:1)

首先,openssl -inform DER -text是一个错误。 openssl程序是一个包装器,它运行一组函数中的一个,由第一个参数标识,在这种情况下必须是x509,所以openssl x509 -inform DER -text

这是一个线索。您的文件是X.509 证书,而不是(仅)公钥。一般的证书,特别是X.509证书,包含公钥,但这与公钥不同。

由于您的文件是X.509证书,请使用X.509类型的CertificateFactory来读取它。模式类似:使用静态.getInstance()方法获取工厂,然后使用.generateCertificate()获取一些输入,这里是一个读取数据的流(直接来自文件,或者如果你有文件,则来自内存)缓冲),并生成一个Certificate对象。 (注意java.security.cert.Certificate而不是过时的和已弃用的java.security.Certificate - 某些IDE可能不会默认为好的。)

如果您想使用证书中的公钥来加密或验证.getPublicKey()上的来电Certificate。如果您想查看其他信息,例如特定于X.509的主题名称或扩展名,请将Certificate强制转换为X509Certificate(也在java.lang.security.cert中)并使用{ {3}}

此外:证书 已使用sha1withRSA签名。 publickey本身是RSA密钥,可以用于任何RSA操作 - 但由于证书声明此密钥属于CA,因此应使用相应的私钥 仅用于签署证书和/或CRL(由KeyUsage控制,如果存在,但除非您已经对其进行了编辑),因此除了验证这些证书和/或CRL之外,使用此公钥进行操作是没用的。由于密钥只有1024位,因此使用比SHA1强的签名散列会被浪费,除了RSA-1024 已经认为不安全(自2014年初)以及使用SHA1-RSA < em> for certificate 被认为有风险,并在明年某个时候被禁止。