Skip to content

Instantly share code, notes, and snippets.

@liweitianux
Last active August 8, 2022 02:17
Show Gist options
  • Save liweitianux/ceb66fdaa3ca9c9085c1a227c8fa6a92 to your computer and use it in GitHub Desktop.
Save liweitianux/ceb66fdaa3ca9c9085c1a227c8fa6a92 to your computer and use it in GitHub Desktop.
Convert PEM key to C bytes array
/*-
* Read Ed25519 public and private keys in DER format.
*/
#include <stdio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
#include "private.h" /* generated by 'pem-to-c.sh' */
int main(void)
{
BIO *bp = BIO_new_fp(stderr, 0);
if (bp == NULL) {
fprintf(stderr, "ERROR: BIO_new_fp() failed\n");
return 1;
}
const unsigned char *p;
long len;
p = _PRIVKEY;
len = (long)sizeof(_PRIVKEY);
EVP_PKEY *pkey = d2i_PrivateKey(EVP_PKEY_ED25519, NULL, &p, len);
if (pkey == NULL) {
fprintf(stderr, "ERROR: d2i_PrivateKey() failed\n");
ERR_print_errors(bp);
return 1;
}
printf("Private Key:\n");
EVP_PKEY_print_private(bp, pkey, 0, NULL);
EVP_PKEY_free(pkey);
p = _PUBKEY;
len = (long)sizeof(_PUBKEY);
/* NOTE: cannot use d2i_PublicKey(EVP_PKEY_ED25519, ...) */
pkey = d2i_PUBKEY(NULL, &p, len);
if (pkey == NULL) {
fprintf(stderr, "ERROR: d2i_PUBKEY() failed\n");
ERR_print_errors(bp);
return 1;
}
printf("Public Key:\n");
EVP_PKEY_print_public(bp, pkey, 0, NULL);
EVP_PKEY_free(pkey);
BIO_free(bp);
return 0;
}
#!/bin/sh
#
# Convert PEM key to C bytes array for easier use and more security.
#
set -o pipefail
set -e
c_hex() {
od -t x1 |
sed -E \
-e 's|^([[:xdigit:]]+)|/* \1 */ |' \
-e 's|\b([[:xdigit:]][[:xdigit:]])\b|0x\1,|g'
}
case $1 in
'' | -h | --help)
echo "usage: ${0##*/} <private.key>" >&2
exit 1
;;
esac
keyfile="$1"
v_privkey=$(openssl rand -hex 8)
v_pubkey=$(openssl rand -hex 8)
privkey=$(openssl pkey -in ${keyfile} -outform DER | c_hex) || exit $?
pubkey=$(openssl pkey -in ${keyfile} -pubout -outform DER | c_hex) || exit $?
cat << _EOF_
#define _PUBKEY _${v_pubkey}
static const unsigned char _${v_pubkey}[] = {
${pubkey}
};
#define _PRIVKEY _${v_privkey}
static const unsigned char _${v_privkey}[] = {
${privkey}
};
_EOF_
  1. Generate Ed25519 private key.
openssl genpkey -algorithm ED25519 -out ed25519.key
  1. Convert to C bytes array.
./pem-to-c.sh ed25519.key

Example output:

#define _PUBKEY _b653c2afa57d511f
static const unsigned char _b653c2afa57d511f[] = {
/* 0000000 */  0x30, 0x2a, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x03, 0x21, 0x00, 0x2a, 0x5c, 0x90, 0x18,
/* 0000020 */  0x01, 0x29, 0x58, 0xd4, 0x1f, 0x13, 0x64, 0x93, 0xa1, 0x54, 0x80, 0x13, 0x96, 0x77, 0x5a, 0x0f,
/* 0000040 */  0xdf, 0xf7, 0x5b, 0x15, 0x17, 0xfb, 0x4d, 0x4f, 0x20, 0x5e, 0x4f, 0x12,
/* 0000054 */ 
};

#define _PRIVKEY _7a88403e83fa8560
static const unsigned char _7a88403e83fa8560[] = {
/* 0000000 */  0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x70, 0x04, 0x22, 0x04, 0x20,
/* 0000020 */  0x49, 0x72, 0x57, 0xc7, 0x9c, 0x74, 0xe4, 0x1f, 0xdd, 0xee, 0x42, 0x50, 0xb8, 0x1d, 0x40, 0x1f,
/* 0000040 */  0x4a, 0xd4, 0x3b, 0x8f, 0x29, 0x70, 0x05, 0x7e, 0x13, 0x2e, 0x37, 0xcb, 0x9c, 0x68, 0xa1, 0xcb,
/* 0000060 */ 
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment