<p>It is Base58 encoded with an initial version byte and 4 checksum bytes on the end.  The version byte indicates the network (production network=128 and test network=239).  The checksum is the first 4 bytes of the double SHA-256 hash of the version and key.</p>

<p>Here is some Java code which creates the private key from the dumped format:
<code><pre>
public DumpedPrivateKey(String string) throws AddressFormatException {
        //
        // Decode the private key
        //
        byte[] decodedKey = Base58.decodeChecked(string);
        int version = (int)decodedKey[0]&amp;0xff;
        if (version != Parameters.DUMPED_PRIVATE_KEY_VERSION)
            throw new AddressFormatException(String.format("Version %d is not correct", version));
        //
        // The private key length is 33 for a compressed public key, otherwise it is 32
        //
        if (decodedKey.length == 33+1 &amp;&amp; decodedKey[33] == (byte)1) {
            isCompressed = true;
            privKeyBytes = Arrays.copyOfRange(decodedKey, 1, decodedKey.length-1);
        } else if (decodedKey.length == 32+1) {
            isCompressed = false;
            privKeyBytes = Arrays.copyOfRange(decodedKey, 1, decodedKey.length);
        } else {
            throw new AddressFormatException("Private key length is incorrect");
        }
    }
</pre></code>
<code><pre>
    public static byte[] decodeChecked(String string) throws AddressFormatException {
        //
        // Decode the string
        //
        byte[] decoded = decode(string);
        if (decoded.length &lt; 4)
            throw new AddressFormatException("Decoded string is too short");
        //
        // Verify the checksum contained in the last 4 bytes
        //
        byte[] bytes = Arrays.copyOfRange(decoded, 0, decoded.length-4);
        byte[] checksum = Arrays.copyOfRange(decoded, decoded.length-4, decoded.length);
        byte[] hash = Arrays.copyOfRange(Utils.doubleDigest(bytes), 0, 4);
        if (!Arrays.equals(hash, checksum))
            throw new AddressFormatException("Checksum is not correct");
        //
        // Return the result without the checksum bytes
        //
        return bytes;
    }
</pre></code></p>

CC BY-SA 3.0
2014-02-09T16:26:12.650Z
Thanks! Can you tell me where you got this from?  I need to sign a message in c# using this private key.  The functional verification code  is here http://stackoverflow.com/a/20400041/328397
makerofthings7
CC BY-SA 3.0
2014-02-10T01:10:20.730Z
It's from my bitcoin node (which is written in Java).  I can send you the Java class if you send me your e-mail address.  It uses BouncyCastle 1.50 for all of the heavy lifting.
ScripterRon
CC BY-SA 3.0
2014-02-10T01:57:11.260Z
I'm using this code here to inspire the C# work in [BitcoinJ](https://code.google.com/p/bitcoinj/source/browse/core/src/main/java/com/google/bitcoin/core/ECKey.java#606)  You can email me at Myname at gmail.  Thanks!
makerofthings7
CC BY-SA 3.0
2014-02-10T04:13:48.003Z
@makerofthings7 Sent
ScripterRon
CC BY-SA 3.0
2014-02-08T18:02:53.333Z
2014-02-08T18:02:53.333Z
ScripterRon
<p>The format is base58check, with 0x80 as version byte (for Bitcoin mainnet, at least), and an optional suffix 0x01 byte to indicate that the corresponding public key is compressed. So combined:</p>

<ul>
<li>base58(0x80 | 32-byte big-endian secret parameter | checksum) for uncompressed public keys</li>
<li>base58(0x80 | 32-byte big-endian secret parameter | 0x01 | checksum) for compressed public keys</li>
</ul>

CC BY-SA 3.0
2014-02-08T19:52:22.000Z
2014-02-08T19:52:22.000Z
Pieter Wuille
<p>I'm trying to use the results of Dumpprivkey to sign a message outside of the QT client, however I'm either having a problem signing or extracting the real value of the key.</p>

<p>What encoding, endian, or format is Dumpprivkey in?  </p>

<p>I assume it's Base58 encoded...</p>

<development><private-key>
What encoding or format is the private key in Dumpprivkey?
makerofthings7
# What encoding or format is the private key in Dumpprivkey?

(Asked by: username_0 on 2014-02-08)

I'm trying to use the results of Dumpprivkey to sign a message outside of the QT client, however I'm either having a problem signing or extracting the real value of the key.

What encoding, endian, or format is Dumpprivkey in?

I assume it's Base58 encoded...

**Tags:** development, private-key


---

## 2 answers

### Answer by username_2 on 2014-02-08. Score: 6 | Accepted answer

The format is base58check, with 0x80 as version byte (for Bitcoin mainnet, at least), and an optional suffix 0x01 byte to indicate that the corresponding public key is compressed. So combined:

* base58(0x80 | 32-byte big-endian secret parameter | checksum) for uncompressed public keys
* base58(0x80 | 32-byte big-endian secret parameter | 0x01 | checksum) for compressed public keys


---

### Answer by username_1 on 2014-02-08. Score: 1

It is Base58 encoded with an initial version byte and 4 checksum bytes on the end.  The version byte indicates the network (production network=128 and test network=239).  The checksum is the first 4 bytes of the double SHA-256 hash of the version and key.
Here is some Java code which creates the private key from the dumped format:

public DumpedPrivateKey(String string) throws AddressFormatException {
        //
        // Decode the private key
        //
        byte[] decodedKey = Base58.decodeChecked(string);
        int version = (int)decodedKey[0]&0xff;
        if (version != Parameters.DUMPED_PRIVATE_KEY_VERSION)
            throw new AddressFormatException(String.format("Version %d is not correct", version));
        //
        // The private key length is 33 for a compressed public key, otherwise it is 32
        //
        if (decodedKey.length == 33+1 && decodedKey[33] == (byte)1) {
            isCompressed = true;
            privKeyBytes = Arrays.copyOfRange(decodedKey, 1, decodedKey.length-1);
        } else if (decodedKey.length == 32+1) {
            isCompressed = false;
            privKeyBytes = Arrays.copyOfRange(decodedKey, 1, decodedKey.length);
        } else {
            throw new AddressFormatException("Private key length is incorrect");
        }
    }


    public static byte[] decodeChecked(String string) throws AddressFormatException {
        //
        // Decode the string
        //
        byte[] decoded = decode(string);
        if (decoded.length < 4)
            throw new AddressFormatException("Decoded string is too short");
        //
        // Verify the checksum contained in the last 4 bytes
        //
        byte[] bytes = Arrays.copyOfRange(decoded, 0, decoded.length-4);
        byte[] checksum = Arrays.copyOfRange(decoded, decoded.length-4, decoded.length);
        byte[] hash = Arrays.copyOfRange(Utils.doubleDigest(bytes), 0, 4);
        if (!Arrays.equals(hash, checksum))
            throw new AddressFormatException("Checksum is not correct");
        //
        // Return the result without the checksum bytes
        //
        return bytes;
    }

> **Comments:**
> **username_0**: Thanks! Can you tell me where you got this from?  I need to sign a message in c# using this private key.  The functional verification code  is here http://stackoverflow.com/a/20400041/328397  
> **username_1**: It's from my bitcoin node (which is written in Java).  I can send you the Java class if you send me your e-mail address.  It uses BouncyCastle 1.50 for all of the heavy lifting.  
> **username_0**: I'm using this code here to inspire the C# work in [BitcoinJ](https://code.google.com/p/bitcoinj/source/browse/core/src/main/java/com/google/bitcoin/core/ECKey.java#606)  You can email me at Myname at gmail.  Thanks!  
> **username_1**: @username_0 Sent  

---

