java.security.spec.InvalidKeySpecException:java.io.IOException:意外的内容结束标记 [英] java.security.spec.InvalidKeySpecException: java.io.IOException: unexpected end-of-contents marker

查看:299
本文介绍了java.security.spec.InvalidKeySpecException:java.io.IOException:意外的内容结束标记的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将.pub文件的内容转换为PublicKey,然后将PublicKey转换回String,以确定转换是否有效并且不更改过程.

I'm trying to convert a .pub file's contents to a PublicKey and then convert the PublicKey back into a String in order to determine if the conversion is working and does not change the key in the process.

id_rsa.pub :

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC0zszKhcZTC8xJidUszmRn4Tr/FxPs04wpCzEstebfTW7Bvqgtt+OdvxoNyYM0LAEnxEF4XhAWcsX7VJJqstZLpDqlKDXFr2d0aVIjksCpZt+ftVRwYHRoERhEOP/UmPFb5rKIkhQbED2kTWg11mW9soc6BhwB3THn/Cyo3t1u2vWjEySgPhKeA3Xzh+5eqV7CUD8V6S7OAT7T9ijf7sRV0R8rwHgTLWJ8+dETnY3L3N0fEaNuaayeNblHqrL53/1+tsBBUF3bAS+1GE6oniSeM/yhtfzf2x+O5MDlVVMbOCC/v+FnfIIEKLA+v1xDSAha7C5cHh82TxToWXsbjqGD me@mail

Converter.java

public static final synchronized PublicKey base64ToPublicKey(final String algorithm, final String base64) throws GeneralSecurityException, IOException {
        BASE64Decoder decoder = new BASE64Decoder();
        byte[] sigBytes2 = decoder.decodeBuffer(base64);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(sigBytes2);
        KeyFactory keyFact = KeyFactory.getInstance(algorithm, "BC");
        return keyFact.generatePublic(x509KeySpec);
    }

    public static final synchronized String publicKeyToBase64(final PublicKey publicKey) throws GeneralSecurityException, IOException {
        byte[] publicKeyBytes = publicKey.getEncoded();
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(publicKeyBytes);
    }

当我跑步时:

PublicKey test1 = base64ToPublicKey("RSA", "AAAAB3NzaC1yc2EAAAADAQABAAABAQC0zszKhcZTC8xJidUszmRn4Tr/FxPs04wpCzEstebfTW7Bvqgtt+OdvxoNyYM0LAEnxEF4XhAWcsX7VJJqstZLpDqlKDXFr2d0aVIjksCpZt+ftVRwYHRoERhEOP/UmPFb5rKIkhQbED2kTWg11mW9soc6BhwB3THn/Cyo3t1u2vWjEySgPhKeA3Xzh+5eqV7CUD8V6S7OAT7T9ijf7sRV0R8rwHgTLWJ8+dETnY3L3N0fEaNuaayeNblHqrL53/1+tsBBUF3bAS+1GE6oniSeM/yhtfzf2x+O5MDlVVMbOCC/v+FnfIIEKLA+v1xDSAha7C5cHh82TxToWXsbjqGD");

我回来了:

java.security.spec.InvalidKeySpecException: java.io.IOException: unexpected end-of-contents marker
    at org.bouncycastle.jce.provider.JDKKeyFactory.engineGeneratePublic(Unknown Source)
    at org.bouncycastle.jce.provider.JDKKeyFactory$RSA.engineGeneratePublic(Unknown Source)
    at java.security.KeyFactory.generatePublic(KeyFactory.java:328)
    at base64ToPublicKey(Converter.java:216)
    at main(Converter.java:283)

推荐答案

OpenSSH公共密钥文件(id_*.pub以及known_hostsauthorized_keys中的条目)使用SSH2-特定于SSH的格式的特定变体,请参见 rfc4716 ,该方法又基于SSH2线格式(链接时) rfc4253 6.6 ,它不是 X.509'格式的Java加密货币使用. (SSH1的OpenSSH文件格式有所不同,但SSH1早已损坏,不应使用.)

OpenSSH public key files (id_*.pub also the entries in known_hosts and authorized_keys) for SSH2 use an OpenSSH-specific variant of an SSH-specific format, see rfc4716 which is in turn based on the SSH2 wire format (as linked) rfc4253 6.6, which is not the 'X.509' format Java crypto uses. (OpenSSH file formats for SSH1 were different, but SSH1 is long broken and should not be used.)

要在Java中进行转换,请参见转换openSSH rsa javax.crypto.Cipher兼容格式的键.

To convert this in Java see convert openSSH rsa key to javax.crypto.Cipher compatible format .

更容易避免该问题.

绕过1:如果您具有相当新的OpenSSH(6.0还可以,不确定较早版本),请使用

Bypass 1: If you have reasonably recent OpenSSH (6.0 is okay, not sure for earlier), use

ssh-keygen -e -m PKCS8 -f id_rsa.pub >pub.pem # change filename as needed

以PEM格式转换为"X.509"(实际上是SubjectPublicKeyInfo aka SPKI). (是的,他们确实使用名称PKCS8来表示SPKI;

to convert to 'X.509' (really SubjectPublicKeyInfo aka SPKI) in PEM form. (Yes they do use the name PKCS8 to mean SPKI; it's crazy.) Then read this in Java by discarding the BEGIN and END lines, decode everything in between (less the line breaks) from base64 to byte[], and put that in X509EncodedKeySpec as you have now. Or if you have OpenSSL you can convert to DER form

openssl rsa -pubin -in pub.pem -out pub.der -outform der # any version
openssl pkey -pubin -in pub.pem -out pub.der -outform der # 1.0.0 up

,然后将没有任何更改的DER文件读入X509EncodedKeySpec.

and then read the DER file with no change at all into an X509EncodedKeySpec.

绕过2:(如果您具有私钥),并且不是OpenSSH的新"格式(自6.5(编辑)以来为可选,默认为) em>(从7.8开始),并且您具有OpenSSL,请使用以下一种方式获取SPKI(对Java友好)格式的公钥:

Bypass 2: if you have the private key, and it is NOT OpenSSH's 'new' format (optional since 6.5 (edit) and default since 7.8), and you have OpenSSL, get the public key in SPKI (Java-friendly) format with one of

openssl rsa -in id_rsa -pubout -out pub.pem # default PEM
openssl rsa -in id_rsa -pubout -out pub.der -outform der # DER
openssl pkey -in id_rsa -pubout -out pub.pem # default PEM, 1.0.0 up
openssl pkey -in id_rsa -pubout -out pub.der -outform der # DER, 1.0.0

这篇关于java.security.spec.InvalidKeySpecException:java.io.IOException:意外的内容结束标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆