сериализация и десериализация объектов с проблемой конструктора без аргументов - PullRequest
0 голосов
/ 28 ноября 2018

Я использую ECIES в своем коде для шифрования.Пример на предоставленном сайте работает без проблем.Мне нужен способ конвертировать ключи (открытый и закрытый ключи) в строку, сериализовать и десериализовать их, используя любые инструменты.Однако, попробовав gson и несколько других методов, я не могу сериализовать и десериализовать ключи.Поскольку существует много объектов классов сторонних производителей, изменить классы нелегко.

Код:

import android.Manifest;
import android.content.Context;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;

import de.flexiprovider.common.exceptions.ECException;
import de.flexiprovider.common.ies.IESParameterSpec;
import de.flexiprovider.core.FlexiCoreProvider;
import de.flexiprovider.ec.FlexiECProvider;
import de.flexiprovider.ec.parameters.CurveParams;
import de.flexiprovider.ec.parameters.CurveRegistry.BrainpoolP160r1;

import static java.security.Security.addProvider;

public class ExampleECIES {
static Context context;
ExampleECIES(Context ctx){
    context=ctx;
}
private ExampleECIES() {
}
static {
    // register the FlexiECProvider
    addProvider(new FlexiECProvider());
}

public static void main(String[] args) throws Exception {

    addProvider(new FlexiCoreProvider());
    addProvider(new FlexiECProvider());

    KeyPairGenerator kpg = KeyPairGenerator.getInstance("ECIES", "FlexiEC");

    CurveParams ecParams = new BrainpoolP160r1();

    kpg.initialize(ecParams, new SecureRandom());
    KeyPair keyPair = kpg.generateKeyPair();
    PublicKey pubKey = keyPair.getPublic();
    PrivateKey privKey = keyPair.getPrivate();

    Gson gson = new Gson();
    String pubKeystr = gson.toJson(pubKey),privKeystr=gson.toJson(privKey);
    Log.e("pubkey->String(Gson)",pubKeystr);
    PublicKey pubKey2 = gson.fromJson(pubKeystr, PublicKey.class);




    // Encrypt

    Cipher cipher = Cipher.getInstance("ECIES", "FlexiEC");

    IESParameterSpec iesParams = new IESParameterSpec("AES128_CBC",
            "HmacSHA1", null, null);

    cipher.init(Cipher.ENCRYPT_MODE, pubKey, iesParams);
    String cleartextFile = context.getExternalFilesDir(null)+"/"+"ECIES-cleartext.txt";
    String ciphertextFile = context.getExternalFilesDir(null)+"/"+"ECIES-ciphertextECIES.txt";



    byte[] block = new byte[64];
    FileInputStream fis = new FileInputStream(cleartextFile);
    FileOutputStream fos = new FileOutputStream(ciphertextFile);
    CipherOutputStream cos = new CipherOutputStream(fos, cipher);
    int i;
    while ((i = fis.read(block)) != -1) {
        cos.write(block, 0, i);
    }
    cos.close();
    // fis.close();

    File testFile1 = new File(cleartextFile);
    Log.e("Location:",cleartextFile);
    Log.e("size of msg:",String.valueOf(testFile1.length()));

    File testFile2 = new File(ciphertextFile);
    Log.e("Location:",ciphertextFile);
    Log.e("size of cipher:",String.valueOf(testFile2.length()));

    // Decrypt




    String cleartextAgainFile = context.getExternalFilesDir(null)+"/"+"ECIES-cleartextAgainECIES.txt";

    cipher.init(Cipher.DECRYPT_MODE, privKey, iesParams);
    fis = new FileInputStream(ciphertextFile);

    CipherInputStream cis = new CipherInputStream(fis, cipher);
    fos = new FileOutputStream(cleartextAgainFile);
    byte[] block1 = new byte[64];
    int length=0;
      while ((i= cis.read(block1)) != -1) {
         fos.write(block1, 0, i);
         length+=1;
     }
    fos.close();
}

}

Журнал:

E/value: Permission Granted, Now you can use local drive .
I/Choreographer: Skipped 47 frames!  The application may be doing too much work on its main thread.
E/pubkey->String(Gson): {"mParams":{"E":{"mA":{"mP":    {"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mQ":{"bigInt":1332297598440044874827085558802491743757193798159}},"g":{"mA":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mX":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":1089473557631435284577962539738532515920566082499}},"mY":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":127912481829969033206777085249718746721365418785}},"mZ":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":1}},"mE":{"mA":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mQ":{"bigInt":1332297598440044874827085558802491743757193798159}},"mP":{"bigInt":1332297598440044874827085558802491743757193798159}},"k":1,"oid":{"value_":[1,3,36,3,3,2,8,1,1,1],"explicit_":true,"optional_":false},"q":{"bigInt":1332297598440044874827085558802491743757193798159},"r":{"bigInt":1332297598440044874827085038830181364212942568457}},"mW":{"mA":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mX":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":628394263989319164273890624957594403688612269204}},"mY":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":1072026760431506144307858012106945103504499745844}},"mZ":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":1}},"mE":{"mA":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mQ":{"bigInt":1332297598440044874827085558802491743757193798159}},"mP":{"bigInt":1332297598440044874827085558802491743757193798159}}}
E/onClick12: Unable to invoke no-args constructor for interface java.security.PublicKey. Register an InstanceCreator with Gson for this type may fix this problem.
E/value: Permission Granted, Now you can use local drive .

Поскольку я недавно начал использовать Java, я ценю ясное и понятное решение.

РЕДАКТИРОВАТЬ: Я исправляю код, заменяя экземпляр класса его реализацией, как показано ниже:

    ...
    Log.e("PublicKey class", String.valueOf(pubKey.getClass()));
    Gson gson = new Gson();
    String pubKeystr = gson.toJson(pubKey),privKeystr=gson.toJson(privKey);
    Log.e("pubkey->String(Gson)",pubKeystr);
    PublicKey pubKey2 = gson.fromJson(pubKeystr, de.flexiprovider.ec.keys.ECPublicKey.class);
    ...

Результат:

E/PublicKey class: class de.flexiprovider.ec.keys.ECPublicKey
E/pubkey->String(Gson): {"mParams":{"E":{"mA":{"mP": 
{"bigInt":1332297598440044874827085558802491743757193798159},"mValue": {"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mQ":{"bigInt":1332297598440044874827085558802491743757193798159}},"g":{"mA":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mX":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":1089473557631435284577962539738532515920566082499}},"mY":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue": {"bigInt":127912481829969033206777085249718746721365418785}},"mZ":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue": {"bigInt":1}},"mE":{"mA":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mQ":{"bigInt":1332297598440044874827085558802491743757193798159}},"mP":{"bigInt":1332297598440044874827085558802491743757193798159}},"k":1,"oid":{"value_":[1,3,36,3,3,2,8,1,1,1],"explicit_":true,"optional_":false},"q":{"bigInt":1332297598440044874827085558802491743757193798159},"r":{"bigInt":1332297598440044874827085038830181364212942568457}},"mW":{"mA":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mX":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":732184415350565563503541898303690594141588218210}},"mY":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":1069191161364546078005104901313515997036014364970}},"mZ":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue": {"bigInt":1}},"mE":{"mA":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":297190522446607939568481567949428902921613329152}},"mB":{"mP":{"bigInt":1332297598440044874827085558802491743757193798159},"mValue":{"bigInt":173245649450172891208247283053495198538671808088}},"mQ":{"bigInt":1332297598440044874827085558802491743757193798159}},"mP":{"bigInt":1332297598440044874827085558802491743757193798159}}}
E/onClick12: Unable to invoke no-args constructor for class 
de.flexiprovider.ec.parameters.CurveParams. Register an InstanceCreator with 
Gson for this type may fix this problem.

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Изучив класс открытого ключа, я понял, что сам класс предоставляет функцию .getstring () для сериализации открытого ключа.После этого я использовал следующий код, чтобы снова преобразовать строку в открытый ключ:

   ...
   byte[] publicBytes =pubKey.getEncoded();
   X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicBytes);
   KeyFactory keyFactory = KeyFactory.getInstance("ECIES", "FlexiEC");
   PublicKey pubKey2 = keyFactory.generatePublic(keySpec);
   ...
0 голосов
/ 28 ноября 2018

Ошибка, кажется, из этой строки:

PublicKey pubKey2 = gson.fromJson(pubKeystr, PublicKey.class);

PublicKey - это интерфейс в Java - означает, что он объявляет набор методов, которые конкретные объекты реализуют для присоединения к этому интерфейсу.В частности, вы не можете создать экземпляр (создать) экземпляр интерфейса;скорее вам нужно указать конкретную реализацию.Итак ... либо:

PublicKey pubKey2 = gson.fromJson(pubKeystr, YourConcretePublicKeyImplementation.class);

ИЛИ, вы конфигурируете gson, чтобы он велел создавать экземпляры "YourConcretePublicKeyImplementation.class", когда ему говорят о десериализации интерфейса PublicKey.

Конечно«YourConcretePublicKeyImplementation.class» - это просто заполнитель - вам нужно использовать (правильную) конкретную реализацию.Для этого вам нужно знать, какая реализация PublicKey была сериализована.

Чтобы сделать это, просто зарегистрируйте (или распечатайте) полное имя класса переменной pubKey, которую вы создали ранее в своем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...