英文:
Verify and Sign JSON Web Tokens from NodeJS to Golang and vice-versa using RSA?
问题
我已经在Golang中生成了一个私钥,该私钥应该用于对以NodeJS编写的其他服务发出的JSON Web Tokens进行签名。
在交换令牌之前,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() // 生成私钥。
identify(id.String(), privateIdentificationKey.publicKey) // 由于类型不匹配,无法工作。
/* 生成私钥。 */
func generatePrivateKey() *rsa.PrivateKey {
secret, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
fmt.Println(err)
}
return secret
}
/* 使Xena-Atila意识到自己的存在。 */
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("无法连接到集中主机。")
}
client := &http.Client{}
response, err := client.Do(request)
defer response.Body.Close()
}
英文:
I've generated a private key in Golang, which should be used to sign JSON Web Tokens issued to the other service coded in NodeJS.
Prior to any exchange of the tokens, NodeJS service should store the public key of the Golang client.
My problem is, I don't know how to export a rsa.PublicKey into a format which is working with NodeJS' npmjs.com/package/jsonwebtoken and do the same in the other direction; meaning providing the Golang client with a public key of the NodeJS service to verify incoming tokens.
Edit:
Code in question https://github.com/zarkones/XENA
Look under the file /xena-apep/main.go lines 16 and 36.
Edit2:
Here is the code in question:
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 := &http.Client{}
response, err := client.Do(request)
defer response.Body.Close()
}
答案1
得分: 1
jwt.sign()
和jwt.verify()
方法来自node-jsonwebtoken库,它们期望使用PEM编码的密钥。因此,NodeJS端将提供PEM编码的公钥或期望一个PEM编码的密钥(可以是X.509/SPKI格式或PKCS#1格式)。
在Go中,密钥的导出和导入是在crypto/x509
包中实现的,PEM编码在encoding/pem
包中实现,RSA在crypto/rsa
包中实现。
使用Go中发布的GeneratePrivateKey()
方法生成私钥和公钥的示例代码如下:
privateKey := GeneratePrivateKey()
publicKey := &privateKey.PublicKey
在Go中,可以使用以下代码将以X.509/SPKI格式导出的PEM编码的公钥:
func ExportSPKIPublicKeyPEM(pubkey *rsa.PublicKey) string {
spkiDER, _ := x509.MarshalPKIXPublicKey(pubkey)
spkiPEM := pem.EncodeToMemory(
&pem.Block{
Type: "PUBLIC KEY",
Bytes: spkiDER,
},
)
return string(spkiPEM)
}
另外,可以使用MarshalPKCS1PublicKey()
方法将以PKCS#1格式导出的PEM编码的公钥。在这种情况下,需要指定Type
为RSA PUBLIC KEY
。
可以使用ASN.1解析器检查导出的密钥,例如在线工具:https://lapo.it/asn1js/
在Go中,可以使用以下代码导入以X.509/SPKI格式编码的PEM公钥:
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()
方法可以导入以PKCS#1格式编码的PEM公钥。
英文:
The jwt.sign()
and and jwt.verify()
method from node-jsonwebtoken expect PEM encoded keys. Therefore, the NodeJS side will provide the public key PEM encoded or expects a PEM encoded key (either in X.509/SPKI format or PKCS#1 format).
Key export and import is implemented in Go in the crypto/x509
package, PEM encoding in the encoding/pem
package, RSA in the crypto/rsa
package.
The generation of a private and public key using the posted GeneratePrivateKey()
method in Go is:
<!-- language: lang-go -->
privateKey := GeneratePrivateKey()
publicKey := &privateKey.PublicKey
Exporting a PEM encoded public key in X.509/SPKI format in Go is possible e.g. with:
<!-- language: lang-go -->
func ExportSPKIPublicKeyPEM(pubkey *rsa.PublicKey) (string){
spkiDER, _ := x509.MarshalPKIXPublicKey(pubkey)
spkiPEM := pem.EncodeToMemory(
&pem.Block{
Type: "PUBLIC KEY",
Bytes: spkiDER,
},
)
return string(spkiPEM)
}
Alternatively, a PEM encoded public key in PKCS#1 format can be exported with MarshalPKCS1PublicKey()
. For this as Type
RSA PUBLIC KEY
must be specified.
The exported key can be checked with an ASN.1 parser, e.g. online with: https://lapo.it/asn1js/
The import of a PEM encoded public key in X.509/SPKI format is possible in Go e.g. with:
<!-- language: lang-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
}
}
With ParsePKCS1PublicKey()
a PEM encoded public key in PKCS#1 format can be imported.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论