How do I load an Elliptic Curve PEM encoded Private Key? [duplicate]

吃可爱长大的小学妹 提交于 2019-12-10 22:18:20

问题


I've generated an elliptic curve private/public key pair using OpenSSL. The private and public keys are PEM encoded. I've figured out how to load the public key thanks to this. However, I can't figure out how to load the private key, as the above message just ends up with an InvalidKeySpecException: key spec not recognized.

I then found this, but it also ends up with an "encoded key spec not recognised". How can I load my private key?

private PrivateKey loadPrivateKey(String location) {
    try {
        // Strip the guarding strings
        byte[] bytes = stripGuardLines(location);

        return KeyFactory.getInstance("ECDH").generatePrivate(new PKCS8EncodedKeySpec(bytes));
    } catch (FileNotFoundException e) {
        LoggerFactory.getLogger("Nectar").error("Failed to find Private KEY: " + location);
        System.exit(1);
    } catch (IOException e) {
        LoggerFactory.getLogger("Nectar").error("IOException while loading Private Key!");
        e.printStackTrace();
        System.exit(1);
    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
        System.exit(1);
    }

    return null;
}

private byte[] stripGuardLines(String location) throws IOException {
    BufferedReader r = new BufferedReader(new FileReader(location));

    String line;
    StringBuilder sb = new StringBuilder();
    while((line = r.readLine()) != null) {
        if(line.contains("EC PRIVATE KEY")) { //Check if guard line
            continue;
        }
        sb.append(line);
    }
    // Guard lines stripped, now decode base64

    return Base64.getDecoder().decode(sb.toString());
}

Here is the private key file:

-----BEGIN EC PRIVATE KEY-----
MIGkAgEBBDD2MFRv6BpJU6/zDI2yBfVbe0oeU1nFAoYMedDGtcdwHyWNJSeiYRBA
pVNzMxPSBLWgBwYFK4EEACKhZANiAAQBttEp/qUGnDlmL+o6KZnVs+RoBnEBEGho
PxSUu1Xfj77QQqfuqHOCRzWXseQA1aZB/h6VQEiFovugtG1G3HaMxxrqLLxb10g2
BMaRcAfZyeqc3O0Ui8XXb1esn0gOrCU=
-----END EC PRIVATE KEY-----

回答1:


Your code outputs only the key itself. It is missing the algorithm specifiers required for PKCS#8 encoded private keys. Fortunately the key itself always has the same size when encoded (it doesn't use any ASN.1 integers, which may have different sizes as far as I can see).

That means that you can simply concatenate the header from another key:

// static header you can put in front
byte[] header = Hex.decode("30 81bf 020100 301006072a8648ce3d020106052b81040022 0481a7");
// your key from the PEM above
byte[] fromPEM = Base64.decode("MIGkAgEBBDD2MFRv6BpJU6/zDI2yBfVbe0oeU1nFAoYMedDGtcdwHyWNJSeiYRBApVNzMxPSBLWgBwYFK4EEACKhZANiAAQBttEp/qUGnDlmL+o6KZnVs+RoBnEBEGhoPxSUu1Xfj77QQqfuqHOCRzWXseQA1aZB/h6VQEiFovugtG1G3HaMxxrqLLxb10g2BMaRcAfZyeqc3O0Ui8XXb1esn0gOrCU=");
byte[] bytes = Arrays.concatenate(header, fromPEM);
PrivateKey ecPrivate = KeyFactory.getInstance("EC").generatePrivate(new PKCS8EncodedKeySpec(bytes));

this code is both Bouncy Castle compatible as compatible with the default implementation in the Java JRE from Oracle.


Note that you might as well use Oracle compatible code to create your key pair as well:

KeyPairGenerator kpGen = KeyPairGenerator.getInstance("EC");
kpGen.initialize(new ECGenParameterSpec("secp384r1"));
KeyPair ecKP = kpGen.generateKeyPair();


来源:https://stackoverflow.com/questions/41927859/how-do-i-load-an-elliptic-curve-pem-encoded-private-key

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!