Как сгенерировать массив байтов из PublicKey

Я использую crypto lib, столкнулся с проблемой: мне нужно преобразовать тип PublicKey в byte[] , как это можно сделать с закрытым ключом:

privkey.D.Bytes()

Как я могу решить эту проблему?


person Folleah    schedule 25.09.2018    source источник
comment
Вы документацию видели? type PublicKey interface{} Это может быть что угодно и, вероятно, не может быть напрямую преобразовано в байтовый срез. Например, RSA PublicKey — это структура, содержащая модуль и показатель степени. Преобразование этого в []byte в любом случае бессмысленно и невозможно. Этот вопрос представляет собой проблему XY. Вместо этого вы должны описать, чего вы действительно пытаетесь достичь, делая это. Тогда мы сможем найти решение истинной основной проблемы.   -  person Michael Hampton    schedule 25.09.2018
comment
@MichaelHampton, я использую другой пакет, в котором мне нужно передать методу массив байтов. Однако, поскольку у меня есть только интерфейс, сделать это невозможно   -  person Folleah    schedule 25.09.2018
comment
Какой еще пакет? Какой метод?   -  person Michael Hampton    schedule 25.09.2018
comment
@MichaelHampton я использую этим способом, мне нужно получить открытый ключ в формат byte[] для использования btcutil.NewAddressPubKey(wif.SerializePubKey(), &chaincfg.MainNetParams)   -  person Folleah    schedule 25.09.2018


Ответы (3)


ecdsa.PrivateKey — это структура:

type PrivateKey struct {
        PublicKey
        D *big.Int
}

Итак, privkey.D.Bytes() возвращает вам байты большого целого числа D.

Аналогично, ecdsa.PublicKey:

type PublicKey struct {
        elliptic.Curve
        X, Y *big.Int
}

Вы можете сделать то же самое с полями pubkey.X и pubkey.Y. Это даст вам 2 отдельных байтовых среза. Если вам нужно объединить их в один, вам нужно придумать какой-то формат, например. кодирование длины первого слайса (результат pubkey.X.Bytes()) с использованием 4 байтов, затем первого слайса, затем длины (снова 4 байта) второго слайса и самого второго слайса.

Лучше всего использовать для этого функцию elliptic.Marshal():

func Marshal(curve Curve, x, y *big.Int) []byte

Marshal преобразует точку в несжатую форму, указанную в разделе 4.3.6 стандарта ANSI X9.62.

Пример его использования:

var pubkey *ecdsa.PublicKey = // ...

data := elliptic.Marshal(pubkey, pubkey.X, pubkey.Y)
person icza    schedule 25.09.2018
comment
@Folleah, хотя это и второстепенно, стоит упомянуть, что для хранения/передачи криптографических материалов было создано как минимум 3 проводных формата — pkcs#7, PFX и pkcs#12 (см. это). Последнее, пожалуй, наиболее распространено в наши дни, и github.com/SSLMate/go-pkcs12 позволяет создавать файлы в формате PKCS#12. контейнеры. См. также. - person kostix; 25.09.2018
comment
Вместо того, чтобы изобретать собственную кодировку, было бы разумно использовать функцию Marshal для получения стандартизированная несжатая точка для представления открытого ключа. Использование формата контейнера, такого как предложенный в комментарии выше, конечно, тоже хороший вариант, но он не похож на хранение D. - person Maarten Bodewes; 25.09.2018
comment
Спасибо, буду изучать эти способы. - person Folleah; 25.09.2018
comment
примечание, если вы используете rsa: privkey.PublicKey.N.Bytes() - person Noam Hacker; 05.10.2018

Для милых людей, которые ищут решение, когда дело доходит до ed25519/crypto. Я ломал голову почти 3 часа, пока не понял:

func getPrivateKey() ed25519.PrivateKey {
    // TODO You fill in this one
}

func main() {
    prvKey := getPrivateKey() // Get the private key

    pubKey := prvKey.Public().(ed25519.PublicKey)
    if !ok {
        log.Errorf("Could not assert the public key to ed25519 public key")
    }
    pubKeyBytes := []byte(pubKey)
}
person George Spasov    schedule 29.06.2020
comment
Я не думаю, что это совершенно правильно - формат закрытых ключей ed25519, по-видимому, представляет собой семя, объединенное с открытым ключом. См. stackoverflow.com/a/44874097/1623885. - person George Aristy; 04.11.2020

Открытый ключ ECDSA имеет тип структуры, определенный ниже.

type PublicKey struct {
        elliptic.Curve
        X, Y *big.Int
}

//Getting the ECDSA public key type from the X509 certificate
pub := certificate.PublicKey.(*ecdsa.PublicKey)

Для преобразования открытого ключа в байтовый массив используйте крипто/эллиптический пакет Marshal Marshal преобразует точку в форму, указанную в разделе 4.3.6 стандарта ANSI X9.62.

pubKeyByte := elliptic.Marshal(pub, pub.X, pub.Y)
person rTom    schedule 03.06.2021