Какая кодировка или формат является закрытым ключом в Dumpprivkey?

Я пытаюсь использовать результаты Dumpprivkey для подписания сообщения за пределами QT-клиента, однако у меня либо есть проблема с подписями или извлечением реального значения ключа.

Какую кодировку, endian или формат Dumpprivkey?

Я предполагаю, что он закодирован в Base58 ...

5 голосов | спросил random65537 8 FebruaryEurope/MoscowbSat, 08 Feb 2014 21:02:03 +0400000000pmSat, 08 Feb 2014 21:02:03 +040014 2014, 21:02:03

2 ответа


5

Формат base58check с байтом версии 0x80 как минимум для базовой сети Bitcoin и необязательным суффиксом 0x01 байт, чтобы указать, что соответствующий открытый ключ сжимается. Итак, комбинированный:

  • base58 (0x80 | 32-байтовый секретный параметр с бай-ином) для несжатых открытых ключей
  • base58 (0x80 | 32-байтовый секретный параметр $ 0x01 | для сжатых открытых ключей
ответил Pieter Wuille 8 FebruaryEurope/MoscowbSat, 08 Feb 2014 23:52:22 +0400000000pmSat, 08 Feb 2014 23:52:22 +040014 2014, 23:52:22
1

Это Base58, закодированное с байтом начальной версии и 4 байтами контрольной суммы на конце. Байт версии указывает сеть (производственная сеть = 128 и тестовая сеть = 239). Контрольная сумма - это первые 4 байта двойного хэша SHA-256 версии и ключа.

Вот код Java, который создает закрытый ключ из сбрасываемого формата:

public DumpedPrivateKey(String string) throws AddressFormatException {
        //
        // Decode the private key
        //
        byte[] decodedKey = Base58.decodeChecked(string);
        int version = (int)decodedKey[0]&0xff;
        if (version != Parameters.DUMPED_PRIVATE_KEY_VERSION)
            throw new AddressFormatException(String.format("Version %d is not correct", version));
        //
        // The private key length is 33 for a compressed public key, otherwise it is 32
        //
        if (decodedKey.length == 33+1 && decodedKey[33] == (byte)1) {
            isCompressed = true;
            privKeyBytes = Arrays.copyOfRange(decodedKey, 1, decodedKey.length-1);
        } else if (decodedKey.length == 32+1) {
            isCompressed = false;
            privKeyBytes = Arrays.copyOfRange(decodedKey, 1, decodedKey.length);
        } else {
            throw new AddressFormatException("Private key length is incorrect");
        }
    }
    public static byte[] decodeChecked(String string) throws AddressFormatException {
        //
        // Decode the string
        //
        byte[] decoded = decode(string);
        if (decoded.length < 4)
            throw new AddressFormatException("Decoded string is too short");
        //
        // Verify the checksum contained in the last 4 bytes
        //
        byte[] bytes = Arrays.copyOfRange(decoded, 0, decoded.length-4);
        byte[] checksum = Arrays.copyOfRange(decoded, decoded.length-4, decoded.length);
        byte[] hash = Arrays.copyOfRange(Utils.doubleDigest(bytes), 0, 4);
        if (!Arrays.equals(hash, checksum))
            throw new AddressFormatException("Checksum is not correct");
        //
        // Return the result without the checksum bytes
        //
        return bytes;
    }

ответил ScripterRon 8 FebruaryEurope/MoscowbSat, 08 Feb 2014 22:02:53 +0400000000pmSat, 08 Feb 2014 22:02:53 +040014 2014, 22:02:53

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132