Байтовый массив ECDSA в ошибку закрытого ключа - PullRequest
0 голосов
/ 29 августа 2018

Я хочу сохранить свой закрытый ключ в файле json (в шестнадцатеричном формате), а затем прочитать его как PrivateKey.

Здесь ключи генерируют функцию

public void generateKeyPair() {
    try {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
        SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
        ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256k1");
        keyGen.initialize(ecSpec,random);
        KeyPair keyPair = keyGen.generateKeyPair();
        privateKey = keyPair.getPrivate();
        publicKey = keyPair.getPublic();
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

Вот как я могу сохранить его в файл json

        a.generateKeyPair();
        byte[] enc_key = a.privateKey.getEncoded();

        StringBuilder key_builder = new StringBuilder();
        for(byte b : enc_key){
            key_builder.append(String.format( "%02X",b));
        }

        String serialized_key = key_builder.toString();
        account.privateKey=serialized_key;
        try (Writer writer = new FileWriter("Output.json")) {
            Gson gson = new GsonBuilder().create();
            gson.toJson(account, writer);
        } catch (IOException e) {
            e.printStackTrace();
        }

И прочитать его из файла

        Gson gson = new GsonBuilder().create();
        try (Reader read1 = new FileReader("Output.json")) {
            account=gson.fromJson(read1,account.getClass());
            byte[] encoded_key=account.privateKey.getBytes();
            a.privateKey = getPrivateKey(encoded_key);

    public static PrivateKey getPrivateKey(byte[] privkey) throws NoSuchAlgorithmException, InvalidKeySpecException {
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privkey);
    KeyFactory kf = null;
    try {
        kf = KeyFactory.getInstance("ECDSA", "BC");
    } catch (NoSuchProviderException e) {
        e.printStackTrace();
    }
    PrivateKey privateKey = kf.generatePrivate(privateKeySpec);
    return privateKey;
}

Сбой функции, и я получаю ошибку

java.security.spec.InvalidKeySpecException: encoded key spec not recognized: failed to construct sequence from byte[]: unknown tag 19 encountered

1 Ответ

0 голосов
/ 30 августа 2018

Вы забыли расшифровать закрытый ключ в шестнадцатеричном формате. Выполнение getBytes этого не сделает.

Кодированный байт начинается с ПОСЛЕДОВАТЕЛЬНОСТИ, тега 0x30. Это в шестнадцатеричном формате, конечно, будет "30" или, в ASCII: 0x33, 0x30: это два первых байта, возвращаемых getBytes. Теперь декодер смотрит на первый байт со значением бита 0b001_10011. Последние 5 битов кодируют значение тега, которое равно 16 + 2 + 1 = 19. Отсюда и конкретная ошибка.

...