J'utilise crypto/rsa
, et essayer de trouver un moyen de correctement enregistrer et charger une clé. Existe-t-il un moyen correct de créer un []byte
d'un rsa.PrivateKey
. Si oui, existe-t-il un moyen de le faire correctement pour un rsa.PublicKey
?
Merci beaucoup à tous.
Vous avez besoin d'une sorte de format pour rassembler la clé. Un format pris en charge par la bibliothèque standard Go peut être trouvé ici: http://golang.org/pkg/crypto/x509/#MarshalPKCS1PrivateKey
func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte
La fonction inverse est http://golang.org/pkg/crypto/x509/#ParsePKCS1PrivateKey .
func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err error)
Cependant, il est relativement standard d'encoder la clé marshalée dans un fichier PEM.
pemdata := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(key),
},
)
Vous pouvez trouver un exemple complet ici .
Voici un extrait de code qui montre l'importation et l'exportation des clés publiques et privées. Il est basé sur les autres réponses qui ont été très utiles, ainsi que sur les pâtes à copier des documents officiels.
package main
import (
"crypto/Rand"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
)
func GenerateRsaKeyPair() (*rsa.PrivateKey, *rsa.PublicKey) {
privkey, _ := rsa.GenerateKey(Rand.Reader, 4096)
return privkey, &privkey.PublicKey
}
func ExportRsaPrivateKeyAsPemStr(privkey *rsa.PrivateKey) string {
privkey_bytes := x509.MarshalPKCS1PrivateKey(privkey)
privkey_pem := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: privkey_bytes,
},
)
return string(privkey_pem)
}
func ParseRsaPrivateKeyFromPemStr(privPEM string) (*rsa.PrivateKey, error) {
block, _ := pem.Decode([]byte(privPEM))
if block == nil {
return nil, errors.New("failed to parse PEM block containing the key")
}
priv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
return priv, nil
}
func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) {
pubkey_bytes, err := x509.MarshalPKIXPublicKey(pubkey)
if err != nil {
return "", err
}
pubkey_pem := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubkey_bytes,
},
)
return string(pubkey_pem), nil
}
func ParseRsaPublicKeyFromPemStr(pubPEM string) (*rsa.PublicKey, error) {
block, _ := pem.Decode([]byte(pubPEM))
if block == nil {
return nil, errors.New("failed to parse PEM block containing the key")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}
switch pub := pub.(type) {
case *rsa.PublicKey:
return pub, nil
default:
break // fall through
}
return nil, errors.New("Key type is not RSA")
}
func main() {
// Create the keys
priv, pub := GenerateRsaKeyPair()
// Export the keys to pem string
priv_pem := ExportRsaPrivateKeyAsPemStr(priv)
pub_pem, _ := ExportRsaPublicKeyAsPemStr(pub)
// Import the keys from pem string
priv_parsed, _ := ParseRsaPrivateKeyFromPemStr(priv_pem)
pub_parsed, _ := ParseRsaPublicKeyFromPemStr(pub_pem)
// Export the newly imported keys
priv_parsed_pem := ExportRsaPrivateKeyAsPemStr(priv_parsed)
pub_parsed_pem, _ := ExportRsaPublicKeyAsPemStr(pub_parsed)
fmt.Println(priv_parsed_pem)
fmt.Println(pub_parsed_pem)
// Check that the exported/imported keys match the original keys
if priv_pem != priv_parsed_pem || pub_pem != pub_parsed_pem {
fmt.Println("Failure: Export and Import did not result in same Keys")
} else {
fmt.Println("Success")
}
}
Puisque la partie clé publique de votre question n'a pas été répondue et que je suis juste tombé sur le même problème et que je l'ai résolu, le voici:
Noter la &
devant l'argument à MarshalPKIXPublicKey
Priv := rsa.GenerateKey(Rand.Reader, 4096)
PubASN1, err := x509.MarshalPKIXPublicKey(&Priv.PublicKey)
if err != nil {
// do something about it
}
pubBytes = pem.EncodeToMemory(&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: PubASN1,
})
ioutil.WriteFile("key.pub", PubBytes, 0644)
Lectures pertinentes:
PS: MarshalPKIXPublicKey accepte également les clés ECDSA, ajustez l'en-tête pem de manière appropriée.