字符串的Java安全密钥和反之亦然

时间:2016-08-22 13:33:08

标签: java security encryption cryptography bouncycastle

在参考我之前的问题here时,我想知道为什么我的代码对于特定输入失败并且适用于另一个。

代码:

import de.flexiprovider.core.FlexiCoreProvider;
import de.flexiprovider.ec.FlexiECProvider;
import de.flexiprovider.ec.parameters.CurveParams;
import de.flexiprovider.ec.parameters.CurveRegistry.BrainpoolP512r1;
import java.io.StringWriter;
import java.security.KeyPair;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;


public class TestClass {

    public TestClass() {
        Security.addProvider(new FlexiCoreProvider());
        Security.addProvider(new FlexiECProvider());
        Security.addProvider(new BouncyCastleProvider());
    }

    public KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES");
        CurveParams ecParams = new BrainpoolP512r1();
        kpg.initialize(ecParams, new SecureRandom());
        KeyPair keyPair = kpg.generateKeyPair();
        return keyPair;
    }

    private String keyToPEMString(Object key) throws Exception {
        StringWriter signedCertificatePEMDataStringWriter = new StringWriter();
        JcaPEMWriter pemWriter = new JcaPEMWriter(signedCertificatePEMDataStringWriter);
        pemWriter.writeObject(key);
        pemWriter.close();
        return signedCertificatePEMDataStringWriter.toString();
    }

    public String[] generateB64EncodedKeyPair() throws Exception {
        String[] publicPrivateKeyPair = new String[2];
        KeyPair keyPair = generateKeyPair();
        publicPrivateKeyPair[0] = keyToPEMString(keyPair.getPublic());
        publicPrivateKeyPair[1] = keyToPEMString(keyPair.getPrivate());
        return publicPrivateKeyPair;
    }

    public String keyToString(Key anyKey) throws Exception {
        return keyToPEMString(anyKey);
    }

    public Key stringToKey(String encodedKey, boolean isPrivate) throws Exception {
        Key key = null;
        KeyFactory keyFactory = KeyFactory.getInstance("ECIES");       //THIS POINT REFERRED
        BASE64Decoder b64 = new BASE64Decoder();
        //System.out.println("Stripped::");
        byte[] keyBytes = null;
        if (isPrivate) {
            encodedKey = encodedKey.replace("-----BEGIN EC PRIVATE KEY-----\r\n", "").replace("-----END EC PRIVATE KEY-----", "");
            //System.out.println(encodedKey);
            keyBytes = b64.decodeBuffer(encodedKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            key = (PrivateKey) keyFactory.generatePrivate(keySpec);

//            PEMParser pemRd = new PEMParser(new StringReader(encodedKey));
//            ASN1ObjectIdentifier ecOID = (ASN1ObjectIdentifier) pemRd.readObject();
//            X9ECParameters ecSpec = ECNamedCurveTable.getByOID(ecOID);
//            if (ecSpec == null) {
//                System.out.println("ecSpec not found for named curve");
//                System.exit(0);
//            }
//            System.out.println(pemRd.readObject());
//            PEMKeyPair pemPair = (PEMKeyPair) pemRd.readObject();
//
//            KeyPair pair = new JcaPEMKeyConverter().setProvider("BC").getKeyPair(pemPair);
//            key = pair.getPrivate();

        } else {
            encodedKey = encodedKey.replace("-----BEGIN PUBLIC KEY-----\r\n", "").replace("-----END PUBLIC KEY-----", "");
            //System.out.println(encodedKey);
            keyBytes = b64.decodeBuffer(encodedKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            key = (PublicKey) keyFactory.generatePublic(keySpec);
        }
        return key;
    }

    public static void main(String[] args) {
        TestClass obj = new TestClass();
        try {

            KeyPair keyPair = obj.generateKeyPair();

            System.out.println("*******************************************");

            System.out.println(obj.keyToPEMString(keyPair.getPublic()));
            System.out.println(obj.keyToPEMString(keyPair.getPrivate()));

            System.out.println("*******************************************");

            System.out.println(obj.stringToKey(obj.keyToPEMString(keyPair.getPublic()), false));
            System.out.println();
            System.out.println(obj.stringToKey(obj.keyToPEMString(keyPair.getPrivate()), true));

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我已成功使用 StringToKey 方法从其PEM格式转换RSA密钥。在将其用于EC密钥时,公钥的转换没有任何麻烦,但私钥不会。

我已经对私钥转换部分中的某个部分发表了评论,我刚刚提到我已尝试过该代码段,但结果不尽如人意。

我需要生成两个密钥并将它们存储到用户计算机上,以便根据需要加载它们。

我拥有的另一个选项是将它们存储在.p12文件中并通过我已成功完成的KeyStore加载它们,但我很想知道PEM转换后的Elliptical Private Keys字符串是否也可以考虑输出或编码转换如下。

以下是上述代码的输出:

*******************************************
-----BEGIN PUBLIC KEY-----
MIGbMBQGByqGSM49AgEGCSskAwMCCAEBDQOBggAERHQce1+hQ4jXBiB7VTKJ1UFR
xqtpqCb5Hh4MiElJNiovj8TFCfONRcYywBlqopCK45JctuMWAelTG0y+sjHB1E7H
2U3wzSMbU5q6qqeK2WoaN1uoeIYV3zBVtOdKtdqUy1fhubWfQUdQDumOCds6dFXD
5N+RHZkt6/hnXtPdWe4=
-----END PUBLIC KEY-----

-----BEGIN EC PRIVATE KEY-----
MEYCAQEEQQCXr25i9d8VeMSRBG5GJ3s+Sxj3UQhyTr9MBoPPhYTlo8dF/+gXUgrE
tW2mDD4MmtofIqWvXoVObW/FjW0NfY/a
-----END EC PRIVATE KEY-----

*******************************************
W =
(44741c7b5fa14388d706207b553289d54151c6ab69a826f91e1e0c884949362a2f8fc4c509f38d45c632c0196aa2908ae3925cb6e31601e9531b4cbeb231c1d4,
 4ec7d94df0cd231b539abaaaa78ad96a1a375ba8788615df3055b4e74ab5da94cb57e1b9b59f4147500ee98e09db3a7455c3e4df911d992debf8675ed3dd59ee)
de.flexiprovider.ec.parameters.CurveRegistry$BrainpoolP512r1@e9ef02e5

de.flexiprovider.api.exceptions.InvalidKeySpecException: codec.asn1.ASN1Exception: ASN.1 type mismatch!
Expected: codec.x509.AlgorithmIdentifier
In      : codec.pkcs8.PrivateKeyInfo
At index: 1
Got tag : 4 and class: 0
        at de.flexiprovider.ec.keys.ECKeyFactory.generatePrivate(ECKeyFactory.java:125)
        at de.flexiprovider.api.keys.KeyFactory.engineGeneratePrivate(KeyFactory.java:61)
        at java.security.KeyFactory.generatePrivate(KeyFactory.java:342)
        at TestClass.stringToKey(TestClass.java:70)
        at TestClass.main(TestClass.java:110)

或者,我对StringToKey方法的KeyFactory行中的内联注释有疑问。我尝试过选择不同的实例,例如: “EC”

“EC”, “BC”

“EC”, “FlexiEC”

“ECDSA”

“ECDSA”, “BC”

“ECDSA”, “FlexiEC”

可悲的是,有效。

如何才能成功将我的EC私钥的PEM转换为私钥? 要么 如何创建可以轻松转换为其原始格式的EC私钥的PEM?

0 个答案:

没有答案