Проверьте и подпишите веб-токены JSON из NodeJS в Golang и наоборот с помощью RSA?

# #node.js #go #jwt #rsa

Вопрос:

Я сгенерировал закрытый ключ в Golang, который следует использовать для подписи веб-токенов JSON, выданных другой службе, закодированной в NodeJS.

Перед любым обменом токенами служба NodeJS должна хранить открытый ключ клиента Golang.

Моя проблема в том, что я не знаю, как экспортировать rsa.PublicKey в формат, который работает с NodeJS’ npmjs.com/package/jsonwebtoken и сделайте то же самое в другом направлении; это означает предоставление клиенту Golang открытого ключа службы NodeJS для проверки входящих токенов.

Редактировать:

Соответствующий код https://github.com/zarkones/XENA Посмотрите в файле /xena-apep/main.go строки 16 и 36.

Правка2:

Вот код, о котором идет речь:

 var privateIdentificationKey = generatePrivateKey() // Generating the private key.

identify(id.String(), privateIdentificationKey.publicKey) // Won't work because of the type miss-match.

/* Generates a private key. */
func generatePrivateKey() *rsa.PrivateKey {
    secret, err := rsa.GenerateKey(rand.Reader, 4096)
    if err != nil {
        fmt.Println(err)
    }
    return secret
}

/* Makes Xena-Atila aware of its existence. */
func identify(id string, identificationKey string) {
    insertionPayload := []byte(`{"id":"`   id   `","identificationKey":"`   identificationKey   `","status":"ALIVE"}`)

    request, err := http.NewRequest("POST", centralizedHost "/v1/clients", bytes.NewBuffer(insertionPayload))
    request.Header.Set("Content-Type", "application/json")
    if err != nil {
        fmt.Println("Unable to connect to the centralized host.")
    }

    client := amp;http.Client{}
    response, err := client.Do(request)
    defer response.Body.Close()
}
 

Комментарии:

1. Согласно документации node- jsonwebtoken, ожидаются ключи, закодированные PEM. Поэтому опубликуйте свой код Go для генерации ключа, который необходимо расширить для экспорта открытого ключа. Вы также должны опубликовать код Go для проверки, который определяет, какой формат открытого ключа ожидает сторона Go.

2. @user9014097 Спасибо за ваше предложение. Вот хранилище github.com/zarkones/XENA Посмотрите в разделе /xena-apep/main.go, строки 16 и 35. Также отредактирую свой вопрос, чтобы включить репозиторий Git.

Ответ №1:

Метод jwt.sign() и и jwt.verify() от узла-jsonwebtoken ожидает ключи, закодированные PEM. Поэтому сторона NodeJS предоставит открытый ключ в кодировке PEM или ожидает ключ в кодировке PEM (либо в формате X. 509/SPKI, либо в формате PKCS#1).

Экспорт и импорт ключей реализован в Go в crypto/x509 пакете, кодировка PEM в encoding/pem пакете, RSA в crypto/rsa пакете.

Генерация закрытого и открытого ключей с использованием GeneratePrivateKey() метода, опубликованного в Go, заключается в:

 privateKey := GeneratePrivateKey()
publicKey := amp;privateKey.PublicKey
 

Экспорт открытого ключа, закодированного PEM, в формате X. 509/SPKI в Go возможен, например, с:

 func ExportSPKIPublicKeyPEM(pubkey *rsa.PublicKey) (string){
    spkiDER, _ := x509.MarshalPKIXPublicKey(pubkey)
    spkiPEM := pem.EncodeToMemory(
        amp;pem.Block{
            Type:  "PUBLIC KEY",
            Bytes: spkiDER,
        },
    )
    return string(spkiPEM)
}
 

В качестве альтернативы можно экспортировать открытый ключ, закодированный PEM, в формате PKCS#1 MarshalPKCS1PublicKey() . Для этого Type RSA PUBLIC KEY необходимо указать as.

Экспортированный ключ можно проверить с помощью анализатора ASN.1, например, онлайн с помощью: https://lapo.it/asn1js/

Импорт открытого ключа, закодированного PEM, в формате X. 509/SPKI возможен в Go, например, с:

 func ImportSPKIPublicKeyPEM(spkiPEM string) (*rsa.PublicKey) {
    body, _ := pem.Decode([]byte(spkiPEM )) 
    publicKey, _ := x509.ParsePKIXPublicKey(body.Bytes)
    if publicKey, ok := publicKey.(*rsa.PublicKey); ok {
        return publicKey
    } else {
        return nil
    }   
}
 

С ParsePKCS1PublicKey() помощью открытого ключа, закодированного PEM, в формате PKCS#1 может быть импортирован.

Комментарии:

1. Спасибо вам за ваше время и ответ. Улучшу свой код на основе того, что вы мне рассказали. Мы примем соответствующий ответ в ближайшее время.

2. Спасибо! Это действительно помогло.