Skip to content

Instantly share code, notes, and snippets.

@csobankesmarki
Last active April 18, 2024 12:39
Show Gist options
  • Save csobankesmarki/ea5e46a5af68623f1d9b442af1528225 to your computer and use it in GitHub Desktop.
Save csobankesmarki/ea5e46a5af68623f1d9b442af1528225 to your computer and use it in GitHub Desktop.
Convert OpenSSH ED25519 to OpenSSL ED25519
(printf \\x30\\x2e\\x02\\x01\\x00\\x30\\x05\\x06\\x03\\x2b\\x65\\x70\\x04\\x22\\x04\\x20;egrep -v "^-" | tr -d '\n' | base64 -d | dd bs=161 skip=1 2>/dev/null | dd bs=32 count=1 2>/dev/null) | openssl pkey -inform der -outform pem
(printf \\x30\\x2a\\x30\\x05\\x06\\x03\\x2b\\x65\\x70\\x03\\x21\\00;egrep -v "^-" | tr -d '\n' | base64 -d | dd bs=62 skip=1 2>/dev/null | dd bs=32 count=1 2>/dev/null) | openssl pkey -pubin -inform der -pubout -outform pem
@csobankesmarki
Copy link
Author

@csobankesmarki
Copy link
Author

both required private key as input

@fernandoenzo
Copy link

Hello, is there any way to do the reverse conversion? I mean, OpenSSL to OpenSSH ED25519. I tried using ssh-keygen -y -f but it doesn't work with this curve. Maybe you have a more manual method, like these scripts, to solve it.

Thanks

@jrd
Copy link

jrd commented Jan 2, 2023

Convert openssh private ed25519 key format to openssl private ed25519 key format:

#!/bin/sh
cat | (
  printf \\x30\\x2e\\x02\\x01\\x00\\x30\\x05\\x06\\x03\\x2b\\x65\\x70\\x04\\x22\\x04\\x20
  grep -Ev '^-' | tr -d '\n' | base64 -d | dd bs=1 skip=161 count=32 status=none
) | openssl pkey

To Convert openssh public ed25519 key format to openssl public ed25519 key format:

#!/bin/sh
cat | (
  printf \\x30\\x2a\\x30\\x05\\x06\\x03\\x2b\\x65\\x70\\x03\\x21\\x00
  cut -d' ' -f2 | base64 -d | dd bs=1 skip=19 status=none
) | openssl pkey -pubin -pubout

@fernandoenzo
Copy link

Thanks for the reply! After much research, I ended up making my own program to do this and other related functions. Maybe you'd like to take a look: https://github.com/fernandoenzo/keysec

@jrd
Copy link

jrd commented Jan 2, 2023

Thank you, this is very interresting! I added this to my stared repo and installed it locally.

I also did conversion in bash scripting the other way around (by reading fucking openssh private format):

Convert openssl private ed25519 key format to openssh private ed25519 key format:

#!/bin/sh
ssl_priv=$(cat)
priv64=$(echo "$ssl_priv"|grep -v '^-'|tr -d '\n'|base64 -d|dd bs=1 skip=16 status=none|base64)
pub64=$(echo "$ssl_priv"|openssl ec -pubout -outform der 2>/dev/null|dd bs=1 skip=12 status=none|base64)
(
  echo '-----BEGIN OPENSSH PRIVATE KEY-----';
  (
    printf 'openssh-key-v1\x00\x00\x00\x00\x04none\x00\x00\x00\x04none\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x003'
    printf '\x00\x00\x00\x0bssh-ed25519\x00\x00\x00 '
    echo "$pub64"|base64 -d
    printf '\x00\x00\x00'
    printf '\x88\x00\x00\x00\x00\x00\x00\x00\x00'
    printf '\x00\x00\x00\x0bssh-ed25519\x00\x00\x00 '
    echo "$pub64"|base64 -d
    printf '\x00\x00\x00@'
    echo "$priv64"|base64 -d
    echo "$pub64"|base64 -d
    printf '\x00\x00\x00\x00\x01\x02\x03\x04\x05'
  ) | base64
  echo '-----END OPENSSH PRIVATE KEY-----'
)

To Convert openssl public ed25519 key format to openssh public ed25519 key format:

#!/bin/sh
printf 'ssh-ed25519 '
(
  printf '\x00\x00\x00\x0bssh-ed25519\x00\x00\x00 '
  cat | grep -v '^-' | base64 -d | dd status=none bs=1 skip=12
) | base64

In case it’s usefull for people who cannot install your python app.

@domo141
Copy link

domo141 commented Feb 2, 2023

These 2 shell scripts to convert from openssl to openssh key formats are great stuff, have to copy those.

Just note that printf '\x00' does not work in all posix shells, (e.g. /bin/dash does not support), \000 etc, octal versions works in those...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment