MiDa
MiDa

Reputation: 225

node-rsa: Encoding too long, using the public key of an ethereum account

I have the following issue:

The main goal is to use the public key of an ethereum-account (form the keystore-file) to encrypt some payload asymmetrically and then decrypt it with the corresponding private key(also from the same keystore-file).

I have extracted the private key from the account-address with the help of this package: keythereum-node

This results in the following hex-formatted privateKey from the specific account address: privateKey: 6dc5aeb2cf14c748da683d1c16491d5b468b5bb1eea3f98c511b6371fdcfb05f

I managed to get the public key from the account by first signing a random chosen string with the private key and then using the signature to recieve the public key (msgHash, v,r,s). I used the ecrecover-method from the ethereumjs-util package for this.

This results in the following hex-formatted publicKey: publicKey: 9f9f445051e788461952124dc08647035c0b31d51f6b4653485723f04c9837adb275d41731309f6125c14ea1546d86a27158eec4164c00bab4724eed925e9c60

So far so good. Now I have both keys ( public-key 512bit and private-key 256bit long). Now I am trying to generate a nodeRsa key (node-Rsa package) by passing the base64 encoded public-key in pem format.

Getting the PrivateKey:

var keyObject = await keythereum.importFromFile(address, keystorePath).then(keyObject => {
        return keyObject;
      }).catch(err => {
        console.log(err);
      });

      var privateKey = await keythereum.recover(password, keyObject).then(privateKey => {
        return privateKey;
      }).catch(err => {
        console.log(err);
      });

      return privateKey;

Getting the PublicKey:

var sig = await web3.eth.accounts.sign("Hello World", privateKey);
var msgHash = sig.messageHash;
var r = sig.r;
var s = sig.s;
var v = sig.v;
msg = recover.toBuffer(msgHash);
var publicKey = recover.ecrecover(msg,v,r,s);

Generating the rsa-key with rsa-node:

var key = new nodeRsa("-----BEGIN RSA PUBLIC KEY-----\n" +
                          "n59EUFHniEYZUhJNwIZHA1wLMdUfa0ZTSFcj8EyYN62yddQXMTCfYSXBTqFUbYai\n" +
                          "cVjuxBZMALq0ck7tkl6cYA==\n" +
                          "-----END RSA PUBLIC KEY-----", "pkcs1-public");

after executing the script the following error is thrown:

{ InvalidAsn1Error: encoding too long
    at newInvalidAsn1Error (/Users/milandavidovic/node_modules/asn1/lib/ber/errors.js:7:13)
    at Reader.readLength (/Users/milandavidovic/node_modules/asn1/lib/ber/reader.js:103:13)
    at Reader.readSequence (/Users/milandavidovic/node_modules/asn1/lib/ber/reader.js:136:16)
    at Object.publicImport (/Users/milandavidovic/node_modules/node-rsa/src/formats/pkcs1.js:122:14)
    at Object.detectAndImport (/Users/milandavidovic/node_modules/node-rsa/src/formats/formats.js:65:48)
    at NodeRSA.module.exports.NodeRSA.importKey (/Users/milandavidovic/node_modules/node-rsa/src/NodeRSA.js:183:22)
    at new NodeRSA (/Users/milandavidovic/node_modules/node-rsa/src/NodeRSA.js:73:18)
    at getPublicKeyFromSignature (/Users/milandavidovic/masterthesis/Scripts/DeployContract.js:280:15)
    at <anonymous> name: 'InvalidAsn1Error', message: 'encoding too long' }
(node:1101) UnhandledPromiseRejectionWarning: InvalidAsn1Error: encoding too long
    at newInvalidAsn1Error (/Users/milandavidovic/node_modules/asn1/lib/ber/errors.js:7:13)
    at Reader.readLength (/Users/milandavidovic/node_modules/asn1/lib/ber/reader.js:103:13)
    at Reader.readSequence (/Users/milandavidovic/node_modules/asn1/lib/ber/reader.js:136:16)
    at Object.publicImport (/Users/milandavidovic/node_modules/node-rsa/src/formats/pkcs1.js:122:14)
    at Object.detectAndImport (/Users/milandavidovic/node_modules/node-rsa/src/formats/formats.js:65:48)
    at NodeRSA.module.exports.NodeRSA.importKey (/Users/milandavidovic/node_modules/node-rsa/src/NodeRSA.js:183:22)
    at new NodeRSA (/Users/milandavidovic/node_modules/node-rsa/src/NodeRSA.js:73:18)
    at getPublicKeyFromSignature (/Users/milandavidovic/masterthesis/Scripts/DeployContract.js:280:15)
    at <anonymous>
(node:1101) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:1101) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I don't understand, why the encoding should be too long. I checked the string multiple times.

If someone has a clue, feel free to write an answer or a suggestion.

Upvotes: 1

Views: 1799

Answers (1)

MiDa
MiDa

Reputation: 225

After some further research I found out, that a key in PEM format doesn't only consist of the base64 encoded raw key with the header and footer. In my case I have to provide a DER structure with the following data:

    RSAPublicKey ::= SEQUENCE {
    modulus           INTEGER,  -- n
    publicExponent    INTEGER   -- e
    }

So my "pem-formatted" key above is not correct. Also my key is not a RSA-Key, it is a secp256k1-Key

Upvotes: 0

Related Questions