Skip to content

Instantly share code, notes, and snippets.

@alanshaw
Last active June 2, 2025 10:09
Show Gist options
  • Save alanshaw/fa1bd92c8524491368d165c50f245591 to your computer and use it in GitHub Desktop.
Save alanshaw/fa1bd92c8524491368d165c50f245591 to your computer and use it in GitHub Desktop.
PEM to DID, libp2p peer ID and base64pad private key.
package main
import (
crypto_ed25519 "crypto/ed25519"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
"github.com/libp2p/go-libp2p/core/crypto"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/storacha/go-ucanto/principal"
ed25519 "github.com/storacha/go-ucanto/principal/ed25519/signer"
)
func main() {
pempath := os.Args[1]
pem, err := os.ReadFile(pempath)
if err != nil {
panic(err)
}
id, err := readPrivateKeyFromPEM(pem)
if err != nil {
panic(err)
}
s, err := ed25519.Format(id)
if err != nil {
panic(err)
}
priv, err := crypto.UnmarshalEd25519PrivateKey(id.Raw())
if err != nil {
panic(err)
}
peerID, err := peer.IDFromPrivateKey(priv)
if err != nil {
panic(err)
}
fmt.Println(id.DID())
fmt.Println(peerID.String())
fmt.Println(s)
}
func readPrivateKeyFromPEM(pemData []byte) (principal.Signer, error) {
var privateKey *crypto_ed25519.PrivateKey
rest := pemData
// Loop until no more blocks
for {
block, remaining := pem.Decode(rest)
if block == nil {
// No more PEM blocks
break
}
rest = remaining
// Look for "PRIVATE KEY"
if block.Type == "PRIVATE KEY" {
parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, fmt.Errorf("failed to parse PKCS#8 private key: %w", err)
}
// We expect a ed25519 private key, cast it
key, ok := parsedKey.(crypto_ed25519.PrivateKey)
if !ok {
return nil, fmt.Errorf("the parsed key is not an ED25519 private key")
}
privateKey = &key
break
}
}
if privateKey == nil {
return nil, fmt.Errorf("could not find a PRIVATE KEY block in the PEM file")
}
return ed25519.FromRaw(*privateKey)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment