0

我正在尝试将.pub文件的内容转换为 a PublicKey,然后将其转换PublicKey回 a String,以确定转换是否正常工作并且不会更改过程中的密钥。

id_rsa.pub

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

转换器.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)
4

1 回答 1

0

SSH2 的 OpenSSH公钥文件id_*.pub也是 和 中的条目known_hostsauthorized_keys使用 SSH 特定格式的 OpenSSH 特定变体,请参阅rfc4716,它又基于 SSH2 线路格式(链接)rfc4253 6.6,它不是 ' X.509' 格式 Java 加密使用. (SSH1 的 OpenSSH 文件格式不同,但 SSH1 早已损坏,不应使用。)

要在 Java 中进行转换,请参阅convert openSSH rsa key to javax.crypto.Cipher compatible format

更容易避免问题。

绕过 1:如果您有相当新的 OpenSSH(6.0 还可以,之前不确定),请使用

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

以 PEM 形式转换为“X.509”(实际上是 SubjectPublicKeyInfo aka SPKI)。(是的,他们确实使用名称 PKCS8 来表示 SPKI;这很疯狂。)然后在 Java 中通过丢弃 BEGIN 和 END 行来阅读此内容,将其之间的所有内容(减去换行符)从 base64 解码为,然后按照您的方式byte[]放入X509EncodedKeySpec现在。或者,如果您有 OpenSSL,您可以转换为 DER 形式

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.

绕过 2:如果您有私钥,并且它不是 OpenSSH 的“新”格式(自 6.5(编辑)起为可选,自 7.8 起为默认),并且您拥有 OpenSSL,请使用 SPKI(Java 友好)格式获取公钥之一

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
于 2016-08-23T18:58:44.727 回答