0

I've been having a really hard time figuring out how to store a Secp256k1 privateKey from multiple libraries (currently on this one for ECIES encryption: https://npm.io/package/@toruslabs/eccrypto).

I have tried encoding and decoding with base64, many implementations of functions that copy array buffer for input encoded string to localStoarge and corresponding output Uint8Array from localStorage, I tried it with IndexedDB, JSON.stringify and parse do not work with binary data, and so many more variations.

When I go through the array buffer elements individually to copy it into a new Uint8Array, I get a similar private key, but with two missing key/field's (parent and offset) which I believe is why every library I have tried so far returns something a long the lines of "bad private key" when I try generating the public key from them.

I am exhausted and I would like some professional insight for my lack of skill in this particular subject. So how can I store (in any way as long as it's client/local) a Secp256k1 private key in a way that if I call it from that persistent client sided data base, they can be used to generate the public keys?

  • Are you generating the private keys on the client side or the server side? – willi123yao Jan 10 '21 at 10:43
  • I am generating them client sided, and hope to store it (any method is fine) client sided –  Jan 10 '21 at 10:59
  • Kindly edit your post and tag the "operating system" (mean the JavaScript framework) that you are using as a possible solution depends on that. Kindly add some minimal example code (even when it's failing) and maybe a **sample** Secp256k1 keypair in PEM encoding, thanks. As most solutions rely on PEM encoded = string keys this key format can easily be stored in a database. – Michael Fehr Jan 10 '21 at 11:22

1 Answers1

1

Apparently, the library that uses the private/public key (in this case being @toruslabs/eccrypto) requires a buffer parameter for the keys.

A simple solution would be to make the NodeJS Buffer available in the browser, through browserify. You will only need to include the NodeJS Buffer class to the window object when creating the browserify file, as shown:

const eccrypto = require('./index');
window.eccrypto = eccrypto;
window.Buffer = Buffer;

Then, generate the bundle file using browserify: browserify main.js -o bundle.js

After this, you will be able to use the Buffer class in your browser, which will make loading the private/public key possible. Sample code here:

<script src="bundle.js"></script>
<script>
  const eccrypto = window.eccrypto;

  const privateKey = eccrypto.generatePrivate();
  const publicKey = eccrypto.getPublic(privateKey);

  // hex string output of private key
  const hexPrivateKey = privateKey.toString('hex')
  console.log(hexPrivateKey); // we can do this as privateKey is a Buffer

  // load private key again
  const newPrivateKey = Buffer.from(hexPrivateKey, 'hex');
 
  const enc = new TextEncoder();

  // code referenced from @toruslabs/eccrypto README
  // Encrypting the message.
  eccrypto.encrypt(publicKey, enc.encode("my testing msg")).then(function (encrypted) {
    // Decrypting the message.
    eccrypto.decrypt(newPrivateKey, encrypted).then(function (plaintext) {
      console.log("Message:", plaintext.toString());
    });
  });
</script>

This should be sufficient to store the hex string of the private key in the localStorage or any client-side database/storage that you will be using.

willi123yao
  • 144
  • 4
  • Thank you for the follow back, I will see if storing the string hexed version of the private key to localStorage works –  Jan 10 '21 at 20:27
  • That's all I was missing? Wow thank you so much! So when I want to store a privatekey to a string I have to hex it first, then from that hex returns the binary data right? –  Jan 10 '21 at 20:53
  • The hex string is basically the hex-encoded binary of the keys, you can store it in any format you want, but hex string is a good example for this case. – willi123yao Jan 11 '21 at 13:07