libp2p / jvm-libp2p

a libp2p implementation for the JVM, written in Kotlin 🔥
https://libp2p.io
Apache License 2.0
260 stars 74 forks source link

Using Ed25519 generated with OpenSSL #358

Open viperey opened 5 months ago

viperey commented 5 months ago

Summary

Hi there. I'm building a JVM based application that relies on pre-generated Ed25519 keys to provide safe communication between peers.

I'm observing some weird behavior that feels like a bug.

Expected behavior

Given a Ed25519 key generated via open ssl:

*@*:/tmp                                                                                                                                                                                                                                                                                                                                                        ⍉
▶ openssl genpkey -algorithm Ed25519 -out ed25519_private.pem && openssl pkey -in ed25519_private.pem -pubout -out ed25519_public.pem

*@*:/tmp                                                                                                                                                                                                                                                                                                                                                        ▶ ll ed25519_p*.pem
Permissions Size User    Date Modified Name
.rw-------   119 viperey  3 Apr 08:50  ed25519_private.pem
.rw-r--r--   113 viperey  3 Apr 08:50  ed25519_public.pem

*@*:/tmp                                                                                                                                                                                                                                                                                                                                                        ▶ cat ed25519_p*.pem
       │ File: ed25519_private.pem
   1   │ -----BEGIN PRIVATE KEY-----
   2   │ MC4CAQAwBQYDK2VwBCIEIH9ZvvvlDocfq7dDFBjsLJEF8oo8N+2VeI7K2QIJkWPx
   3   │ -----END PRIVATE KEY-----
──────────────────────────────────────────────────────────       │ File: ed25519_public.pem
   1   │ -----BEGIN PUBLIC KEY-----
   2   │ MCowBQYDK2VwAyEA08ZD6jfldUOHtv/77PFbVWCq+ZnrYQm3u8ucW3bh0fw=
   3   │ -----END PUBLIC KEY-----
───────┴──────────────────────────────────────────────────

When a host is created with the private key, the peerId derivated via (private key in disk -> public key generated by lib-p2p -> peerId) won't be the same as if generating one via (public key in disk -> peerId).

Some (scala) code to observe this behavior:

  val privateKeyFs: PrivKey = Ed25519Kt
    .unmarshalEd25519PrivateKey(
      Base64.getDecoder.decode(
        "MC4CAQAwBQYDK2VwBCIEIH9ZvvvlDocfq7dDFBjsLJEF8oo8N+2VeI7K2QIJkWPx"
      )
    )
    val publicKeyFs = privateKeyFs.publicKey()
    val publicKeyFsStr = Base64.getEncoder.encodeToString(publicKeyFsStr.bytes())
    val peerIdFS: PeerId = PeerId.fromPubKey(publicKeyFs)

    val directlyPublicKey = Ed25519Kt.unmarshalEd25519PublicKey(
      Base64.getDecoder.decode("MCowBQYDK2VwAyEA08ZD6jfldUOHtv/77PFbVWCq+ZnrYQm3u8ucW3bh0fw=")
    )
    val directlyPublicKeyStr  = Base64.getEncoder.encodeToString(directlyPublicKeyStr.bytes())
    val directlyPeerId: PeerId = PeerId.fromPubKey(
      directlyPublicKey
    )

    assert(directlyPublicKeyStr == publicKeyFsStr)
    assert(directlyPeerId == peerIdFS)

(The assertions fails)

Actual behavior

The public key values do not match and neither the peerId values. In both (private and public) cases the unmarshalling works, but the values simply do not match.

image

Relevant log output

No response

Possible Solution

No response

Version

1.1.0-RELEASE

Would you like to work on fixing this bug ?

Maybe