<p>For Javascript/Node, I highly recommend this library:</p>

<p><a href="https://www.npmjs.com/package/key-encoder" rel="nofollow noreferrer">https://www.npmjs.com/package/key-encoder</a></p>

<p><a href="https://github.com/blockstack/key-encoder-js/" rel="nofollow noreferrer">https://github.com/blockstack/key-encoder-js/</a></p>

<p>It does exactly what you need.</p>

CC BY-SA 4.0
2019-08-29T13:04:47.017Z
2019-08-29T13:04:47.017Z
celeduc
<p>when I verify your self created privkey, I get this error:</p>

<blockquote>
  <p>error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long</p>
</blockquote>

<p>I couldn't see how you created your privkey, but the way to go is through the ASN.1 structure, and then base64 it. 
When using OpenSSL to sign, you must also make sure you are signing hex data, and not strings (this is explained in the answer of the link I provided in my comment). </p>

<p>The ASN1 structure for a privkey looks like this:</p>

<pre><code># ASN.1 STRUCTURE FOR PRIVATE KEY:
#   30  &lt;-- declares the start of an ASN.1 sequence
#   74  &lt;-- length of following sequence 
#   02  &lt;-- declares the start of an integer
#   01  &lt;-- length of integer in bytes (1 byte)
#   01  &lt;-- value of integer (1)
#   04  &lt;-- declares the start of an "octet string"
#   20  &lt;-- length of string to follow (32 bytes)
#           3cd0560f5b27591916c643 ... a738d2e912990dcc573715d2c 
#           \--------------------------------------------------/
#            this is the private key 
#   a0   &lt;-- declares the start of context-specific tag 0
#   07   &lt;-- length of context-specific tag 
#   06   &lt;-- declares the start of an object ID
#   05   &lt;-- length of object ID to follow 
#   2b 81 04 00 0a &lt;-- the object ID of the curve secp256k1
#   a1   &lt;-- declares the start of context-specific tag 1
#   44   &lt;-- declares the length of context-sepcifc tag (68 bytes)
#   03   &lt;-- declares the start of a bit string
#   42   &lt;-- length of bit string to follow (66 bytes)
#   00   &lt;-- ??
#            04 f1 44 f0 dc 00 80 af d2 b7 3f 13 37 6c ... 05 49 cd 83 f4 58 56 1e
#            \-------------------------------------------------------------------/
#             this is the public key
</code></pre>

<p>Using your privkey, I derived the pukey, and get this pem format:</p>

<pre><code>### use pre defined ASN.1 strings to concatenate PEM privkey
  a pre_string : 30740201010420
  the privkey  : 3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c
  a mid_string : a00706052b8104000aa144034200
  the pubkey   : 04BF350D2821375158A608B51E3E898E507FE47F2D2E8C774DE4A9A7EDECF74ED
                 A24243CB992C5673A07FA5B3A66CD8E3ACEF2809D0E380A0C7929DAB1E5D5438B

### base64 privkey file and put some nice surroundings
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDzQVg9bJ1kZFsZDoLeqadA4OTgKc40ukSmQ3MVzcV0soAcGBSuBBAAK
oUQDQgAEvzUNKCE3UVimCLUePomOUH/kfy0ujHdN5Kmn7ez3TtokJDy5ksVnOgf6
WzpmzY46zvKAnQ44Cgx5Kdqx5dVDiw==
-----END EC PRIVATE KEY-----
</code></pre>

<p>using asn1parse, the result looks like this:</p>

<pre><code>openssl asn1parse -in privkey.pem
    0:d=0  hl=2 l= 116 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:3CD0560F5B27591916C643A0B7AA69D03839380A738D2E912990DCC573715D2C
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1
   48:d=1  hl=2 l=  68 cons: cont [ 1 ]        
   50:d=2  hl=2 l=  66 prim: BIT STRING 
</code></pre>

<p><strong>putting all together:</strong></p>

<pre><code>#!/bin/sh 
###############################################
# convert from chars to hex
printf $( echo 456f9e1b6184d770f1a240da9a3c4458e55b6b4ba2244dd21404db30b3131b94 | sed 's/[[:xdigit:]]\{2\}/\\x&amp;/g' ) &gt; tmp_utx.hex

echo "The private key in HEX format: "
echo 3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c  
# The private key in PEM format:
echo "-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDzQVg9bJ1kZFsZDoLeqadA4OTgKc40ukSmQ3MVzcV0soAcGBSuBBAAK
oUQDQgAEvzUNKCE3UVimCLUePomOUH/kfy0ujHdN5Kmn7ez3TtokJDy5ksVnOgf6
WzpmzY46zvKAnQ44Cgx5Kdqx5dVDiw==
-----END EC PRIVATE KEY-----" &gt; privkey.pem

# the signing process 
#  prepare pubkey:
    openssl ec -in privkey.pem -pubout -out pubkey.pem
#  sign:
    openssl dgst -sign privkey.pem  -sha256 -hex tmp_utx.hex
    openssl dgst -sign privkey.pem  -sha256 tmp_utx.hex &gt; tmp_sig.hex
#  verify:
    openssl dgst -verify pubkey.pem -sha256 -signature tmp_sig.hex tmp_utx.hex

echo " "
</code></pre>

<p>returns:</p>

<blockquote>
  <p>Verified OK</p>
</blockquote>

CC BY-SA 3.0
2017-12-27T07:10:23.613Z
Thank you very much for your detailed response! It's very helpful. I thought all I need is to convert the hex string (my btc private key) to binary and then base64 it. One thing I did not understand is why do I need my public key in order to generate a .pem private key?
user2298995
CC BY-SA 3.0
2017-12-27T07:41:54.663Z
By the way, even with the base64 privkey you provided above, the openssl_sign function still does not seem to accept it as a valid key.
user2298995
CC BY-SA 3.0
2017-12-27T08:00:49.070Z
I further extended my answer, with the "raw" openssl commands. Below the secton "utting all together". This is as much as I can do... I don't know how to realize in PHP.
pebwindkraft
CC BY-SA 4.0
2019-11-27T23:09:39.390Z
How do you derive the public key from the private key?
Gavin S. Yancey
CC BY-SA 4.0
2019-11-28T16:40:10.447Z
I don't :-) Openssl does it for me, at line "#  prepare pubkey:", it uses openssl, the input is the privkey, output is public key.
pebwindkraft
CC BY-SA 3.0
2017-12-26T19:49:42.667Z
2017-12-27T07:59:20.060Z
2017-12-27T07:59:20.060Z
pebwindkraft
<p>Given a private key: <code>3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c</code>,
And a tx hash: <code>456f9e1b6184d770f1a240da9a3c4458e55b6b4ba2244dd21404db30b3131b94</code>, I would like to sign, using SSL and PHP. Converting the private key to a pem format (so SSL can use it), I generate the following base64 string: <code>PNBWD1snWRkWxkOgt6pp0Dg5OApzjS6RKZDcxXNxXSw=</code>. So a valid pem format should be:</p>

<p><code>-----BEGIN EC PRIVATE KEY-----
PNBWD1snWRkWxkOgt6pp0Dg5OApzjS6RKZDcxXNxXSw=
-----END EC PRIVATE KEY-----</code></p>

<p>However, it does not seem to be working. I'm using the following function: <code>openssl_sign($hash, $signature, $private_key, OPENSSL_ALGO_SHA256)</code>.</p>

<p>But when I generate a random private key using SSL, for example:
<code>
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEINhhp8dYz31X+KWq3u/gutJthvW2puUbB9AOIul/v2SOoAoGCCqGSM49
AwEHoUQDQgAE0jE7TIszCklw//SGyYW0+z38PUxwfkip9WS4UUn68f7D78D6ZQ/O
dlPisC1fQZrUrFrik/wq7E4Xwrqs3n3b5w==
-----END EC PRIVATE KEY-----
</code></p>

<p>The function does work. What is wrong with the pem format that I'm generating using an existing private key?</p>

CC BY-SA 3.0
2017-12-26T16:12:22.077Z
I had the same problem, and described it here: https://bitcoin.stackexchange.com/questions/46455/verifying-a-bitcoin-trx-on-the-unix-cmd-line-with-openssl
pebwindkraft
CC BY-SA 3.0
2017-12-26T19:01:43.950Z
Actually I have looked at this stackexchange item a few hours ago. Unfortunately it did not answer my question.
user2298995
<signature><ssl>
Signing transaction with SSL - private key to PEM
user2298995
# Signing transaction with SSL - private key to PEM

(Asked by: username_0 on 2017-12-26)

Given a private key: `3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c`,
And a tx hash: `456f9e1b6184d770f1a240da9a3c4458e55b6b4ba2244dd21404db30b3131b94`, I would like to sign, using SSL and PHP. Converting the private key to a pem format (so SSL can use it), I generate the following base64 string: `PNBWD1snWRkWxkOgt6pp0Dg5OApzjS6RKZDcxXNxXSw=`. So a valid pem format should be:

`-----BEGIN EC PRIVATE KEY-----
PNBWD1snWRkWxkOgt6pp0Dg5OApzjS6RKZDcxXNxXSw=
-----END EC PRIVATE KEY-----`

However, it does not seem to be working. I'm using the following function: `openssl_sign($hash, $signature, $private_key, OPENSSL_ALGO_SHA256)`.

But when I generate a random private key using SSL, for example:
`-----BEGIN EC PRIVATE KEY-----
MHcCAQEEINhhp8dYz31X+KWq3u/gutJthvW2puUbB9AOIul/v2SOoAoGCCqGSM49
AwEHoUQDQgAE0jE7TIszCklw//SGyYW0+z38PUxwfkip9WS4UUn68f7D78D6ZQ/O
dlPisC1fQZrUrFrik/wq7E4Xwrqs3n3b5w==
-----END EC PRIVATE KEY-----`

The function does work. What is wrong with the pem format that I'm generating using an existing private key?

**Tags:** signature, ssl

> **Comments:**
> **username_1**: I had the same problem, and described it here: https://bitcoin.stackexchange.com/questions/46455/verifying-a-bitcoin-trx-on-the-unix-cmd-line-with-openssl  
> **username_0**: Actually I have looked at this stackexchange item a few hours ago. Unfortunately it did not answer my question.  

---

## 2 answers

### Answer by username_1 on 2017-12-26. Score: 8 | Accepted answer

when I verify your self created privkey, I get this error:

> error:0D07207B:asn1 encoding routines:ASN1\_get\_object:header too long

I couldn't see how you created your privkey, but the way to go is through the ASN.1 structure, and then base64 it.
When using OpenSSL to sign, you must also make sure you are signing hex data, and not strings (this is explained in the answer of the link I provided in my comment).

The ASN1 structure for a privkey looks like this:

```
# ASN.1 STRUCTURE FOR PRIVATE KEY:
#   30  <-- declares the start of an ASN.1 sequence
#   74  <-- length of following sequence 
#   02  <-- declares the start of an integer
#   01  <-- length of integer in bytes (1 byte)
#   01  <-- value of integer (1)
#   04  <-- declares the start of an "octet string"
#   20  <-- length of string to follow (32 bytes)
#           3cd0560f5b27591916c643 ... a738d2e912990dcc573715d2c 
#           \--------------------------------------------------/
#            this is the private key 
#   a0   <-- declares the start of context-specific tag 0
#   07   <-- length of context-specific tag 
#   06   <-- declares the start of an object ID
#   05   <-- length of object ID to follow 
#   2b 81 04 00 0a <-- the object ID of the curve secp256k1
#   a1   <-- declares the start of context-specific tag 1
#   44   <-- declares the length of context-sepcifc tag (68 bytes)
#   03   <-- declares the start of a bit string
#   42   <-- length of bit string to follow (66 bytes)
#   00   <-- ??
#            04 f1 44 f0 dc 00 80 af d2 b7 3f 13 37 6c ... 05 49 cd 83 f4 58 56 1e
#            \-------------------------------------------------------------------/
#             this is the public key

```

Using your privkey, I derived the pukey, and get this pem format:

```
### use pre defined ASN.1 strings to concatenate PEM privkey
  a pre_string : 30740201010420
  the privkey  : 3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c
  a mid_string : a00706052b8104000aa144034200
  the pubkey   : 04BF350D2821375158A608B51E3E898E507FE47F2D2E8C774DE4A9A7EDECF74ED
                 A24243CB992C5673A07FA5B3A66CD8E3ACEF2809D0E380A0C7929DAB1E5D5438B

### base64 privkey file and put some nice surroundings
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDzQVg9bJ1kZFsZDoLeqadA4OTgKc40ukSmQ3MVzcV0soAcGBSuBBAAK
oUQDQgAEvzUNKCE3UVimCLUePomOUH/kfy0ujHdN5Kmn7ez3TtokJDy5ksVnOgf6
WzpmzY46zvKAnQ44Cgx5Kdqx5dVDiw==
-----END EC PRIVATE KEY-----

```

using asn1parse, the result looks like this:

```
openssl asn1parse -in privkey.pem
    0:d=0  hl=2 l= 116 cons: SEQUENCE          
    2:d=1  hl=2 l=   1 prim: INTEGER           :01
    5:d=1  hl=2 l=  32 prim: OCTET STRING      [HEX DUMP]:3CD0560F5B27591916C643A0B7AA69D03839380A738D2E912990DCC573715D2C
   39:d=1  hl=2 l=   7 cons: cont [ 0 ]        
   41:d=2  hl=2 l=   5 prim: OBJECT            :secp256k1
   48:d=1  hl=2 l=  68 cons: cont [ 1 ]        
   50:d=2  hl=2 l=  66 prim: BIT STRING 

```

**putting all together:**

```
#!/bin/sh 
###############################################
# convert from chars to hex
printf $( echo 456f9e1b6184d770f1a240da9a3c4458e55b6b4ba2244dd21404db30b3131b94 | sed 's/[[:xdigit:]]\{2\}/\\x&/g' ) > tmp_utx.hex

echo "The private key in HEX format: "
echo 3cd0560f5b27591916c643a0b7aa69d03839380a738d2e912990dcc573715d2c  
# The private key in PEM format:
echo "-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDzQVg9bJ1kZFsZDoLeqadA4OTgKc40ukSmQ3MVzcV0soAcGBSuBBAAK
oUQDQgAEvzUNKCE3UVimCLUePomOUH/kfy0ujHdN5Kmn7ez3TtokJDy5ksVnOgf6
WzpmzY46zvKAnQ44Cgx5Kdqx5dVDiw==
-----END EC PRIVATE KEY-----" > privkey.pem

# the signing process 
#  prepare pubkey:
    openssl ec -in privkey.pem -pubout -out pubkey.pem
#  sign:
    openssl dgst -sign privkey.pem  -sha256 -hex tmp_utx.hex
    openssl dgst -sign privkey.pem  -sha256 tmp_utx.hex > tmp_sig.hex
#  verify:
    openssl dgst -verify pubkey.pem -sha256 -signature tmp_sig.hex tmp_utx.hex

echo " "

```

returns:

> Verified OK

> **Comments:**
> **username_0**: Thank you very much for your detailed response! It's very helpful. I thought all I need is to convert the hex string (my btc private key) to binary and then base64 it. One thing I did not understand is why do I need my public key in order to generate a .pem private key?  
> **username_0**: By the way, even with the base64 privkey you provided above, the openssl_sign function still does not seem to accept it as a valid key.  
> **username_1**: I further extended my answer, with the "raw" openssl commands. Below the secton "utting all together". This is as much as I can do... I don't know how to realize in PHP.  
> **username_3**: How do you derive the public key from the private key?  
> **username_1**: I don't :-) Openssl does it for me, at line "#  prepare pubkey:", it uses openssl, the input is the privkey, output is public key.  

---

### Answer by username_2 on 2019-08-29. Score: 0

For Javascript/Node, I highly recommend this library:

<https://www.npmjs.com/package/key-encoder>

<https://github.com/blockstack/key-encoder-js/>

It does exactly what you need.


---

