根据文件的字符串创建java PrivateKey和PublicKey

问题描述 投票:-1回答:2

早安,

[还有另一个第三方需要我的Web应用程序以加密格式向他们发送一些数据。因此,他们向我发送了一些指导,但我对此并不熟悉,我正尝试在google上搜索,但看起来我是google的错误方式。

该指南如下:

  1. 运行openssl命令生成私钥:

    openssl ecparam -name prime256v1 -genkey -out myprivate.pem

运行此命令后,我输出了一个priv.pem文件,我看到里面有一些以'=='结尾的键,如下所示:

-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEILefWfeuZOgnbDlxpwo3uQ2xQXfhXHUPTS+vKzvVZdCToAoGCCqGSM49
AwEHoUQDQgAE4MeQspGRJ1qdpweBfiaT5P84alZdga1f7mSpa5HqXTH58u0ZWJUQ
J7ToU/bUOPITh4FX07AV6wrgFCmwtUenDQ==
-----END EC PRIVATE KEY-----
  1. 第二个运行openssl命令以生成公用密钥,然后将其发送:

    openssl ec -in myprivate.pem -pubout -out mypublic.pem

  2. 将私钥转换为pkcs8格式:

    openssl pkcs8 -topk8 -nocrypt -in myprivate.pem -out mypkcs8.pem

  3. 第三方将以字符串格式给我一个公共密钥,然后要求我生成一个秘密密钥,并向我提供一些如下的Java代码:

第一个是生成密钥,第二个是加密:

public static SecretKey generateSharedSecret(PrivateKey privateKey,
            PublicKey publicKey) {
        try {
            KeyAgreement keyAgreement = KeyAgreement.getInstance( "ECDH" );
            keyAgreement.init( privateKey );
            keyAgreement.doPhase( publicKey, true );
            SecretKeySpec key = new SecretKeySpec(
                    keyAgreement.generateSecret( ), "AES" );
            return key;
        } catch ( Exception e ) {
            // TODO Auto-generated catch block
            e.printStackTrace( );
            return null;
        }
    }

public static String encryptString(SecretKey key, String plainText) {
        try {
            String myIv = "Testing @ IV!";
            byte[] iv = myIv.getBytes( "UTF-8" );
            IvParameterSpec ivSpec = new IvParameterSpec( iv );
            Cipher cipher = Cipher.getInstance( "AES / CBC / PKCS5Padding" );
            byte[] plainTextBytes = plainText.getBytes( "UTF-8" );
            byte[] cipherText;
            cipher.init( Cipher.ENCRYPT_MODE, key, ivSpec );
            cipherText = new byte[cipher.getOutputSize( plainTextBytes.length )];
            int encryptLength = cipher.update( plainTextBytes, 0,
                    plainTextBytes.length, cipherText, 0 );
            encryptLength += cipher.doFinal( cipherText, encryptLength );
            return bytesToHex( cipherText );
        } catch ( Exception e ) {
            e.printStackTrace( );
            return null;
        }
    }

还有字节到十六进制字符串的方法:

public static String bytesToHex(byte[] byteArray) {
    StringBuffer hexStringBuffer = new StringBuffer( );
    for ( int i = 0; i < byteArray.length; i++ ) {
        hexStringBuffer.append( String.format( "%02X", byteArray[ i ] ) );
    }
    return hexStringBuffer.toString( );
}

[我通过使用openssl命令自生成了一个私钥和一个公钥,但是第4步告诉我它们也会给我一个公钥,因此我不知道应该使用哪个公钥。] >

而且,如何将String转换为Java PrivateKeyPublicKey对象?

*加*

我尝试将der文件转换为java PublicKey对象,它看起来可行。在此之前,我使用openssl命令将pem转换为der:
openssl pkey -pubin -in ecpubkey.pem -outform der -out ecpubkey.der

这是Java代码:

        File f = new File("/home/my/Desktop/key/ecpubkey.der");
        FileInputStream fis = new FileInputStream(f);
        DataInputStream dis = new DataInputStream(fis);
        byte[] keyBytes = new byte[(int) f.length()];
        dis.readFully(keyBytes);
        dis.close();

        KeyFactory fact = KeyFactory.getInstance("EC");
        PublicKey theirpub = fact.generatePublic(new X509EncodedKeySpec(keyBytes));

但是,当我尝试将der文件转换为java PrivateKey对象时,我碰到了java.security.spec.InvalidKeySpecException: java.io.IOException: insufficient data,这是我所做的:

openssl ecparam -name prime256v1 -genkey -out priv.pem
openssl pkcs8 -topk8 -nocrypt -in priv.pem -outform der -out priv.der

以下是我的Java代码:

        File f2 = new File("/home/my/Desktop/key/priv.der");
        FileInputStream fis2 = new FileInputStream(f2);
        DataInputStream dis2 = new DataInputStream(fis2);
        byte[] keyBytes2 = new byte[(int) f.length()];
        dis2.readFully(keyBytes2);
        dis2.close();

        KeyFactory fact2 = KeyFactory.getInstance("EC");
        PrivateKey pKey = fact2.generatePrivate( new PKCS8EncodedKeySpec(keyBytes2) ); // this line hit insufficient data

[早上好,还有另一个第三方需要我的Web应用程序以加密格式向他们发送一些数据。因此,他们向我发送了一些指导,但是我对此并不熟悉,我正在尝试...

java encryption private-key public-key secret-key
2个回答
2
投票

Diffie-Hellman在wikipedia中得到了很好的解释-大概是这里的数百个Q以及与之有关的crypto.SX和security.SX的解释,但是我很难找到它们。简而言之:


0
投票

基于dave_thompson_085的说明和代码,我设法通过以下命令创建了Java PublicKey和Privatekey:

public static PublicKey getPublicKey(String filename) throws IOException, GeneralSecurityException {
    String publicKeyPEM = getKey(filename);
    return getPublicKeyFromString(publicKeyPEM);
}

private static String getKey(String filename) throws IOException {
    // Read key from file
    String strKeyPEM = "";
    BufferedReader br = new BufferedReader(new FileReader(filename));
    String line;
    while ((line = br.readLine()) != null) {
        strKeyPEM += line + "\n";
    }
    br.close();
    return strKeyPEM;
}

public static PublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException {
    String publicKeyPEM = key;
    publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", "");
    publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
    BASE64Decoder b = new BASE64Decoder();
    byte[] encoded = b.decodeBuffer(publicKeyPEM);
    KeyFactory kf = KeyFactory.getInstance("EC");
    PublicKey pubKey = (PublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded));
    return pubKey;
}
© www.soinside.com 2019 - 2024. All rights reserved.