java.security.spec.InvalidKeySpecException:java.io.IOException:意外的内容结束标记 [英] java.security.spec.InvalidKeySpecException: java.io.IOException: unexpected end-of-contents marker
问题描述
我正在尝试将.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_hosts
和authorized_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屋!