2

I come from this other question which was left unanswered:

Well, I discovered something new. I still can't import my certificate and when I try to execute my Node/express app, it fails with the same error, but now I think that somehow, the fs package is not reading my .pem files correctly.

Take a look:

// Setup HTTPS
const httpsPort = 3443;
const options = {
  key: fs.readFileSync("./key.pem"),
  cert: fs.readFileSync("./cert.pem")
};

console.log("KEY: ", options.key)
console.log("CERT: ", options.cert)

var secureServer = https.createServer(options, app).listen(httpsPort, () => {
    console.log(">> CentraliZr listening at port "+httpsPort);
});

I get the following output:

C:\Zerok\dev\centralizr>node index.js
KEY:  <Buffer 2d 2d 2d 2d 2d 42 45 47 49 4e 20 50 52 49 56 41 54 45 20 4b 45 59 2d 2d 2d 2d 2d 0d 0a 70 52 39 37 51 33 6f 50 5a 5a 59 75 39 46 6c 31 54 6d 30 0d 0a ... >
CERT:  <Buffer 2d 2d 2d 2d 2d 42 45 47 49 4e 20 43 45 52 54 49 46 49 43 41 54 45 2d 2d 2d 2d 2d 0a 4d 49 49 45 4a 54 43 43 41 36 79 67 41 77 49 42 41 67 49 49 48 48 ... >
_tls_common.js:85
      c.context.setKey(options.key, options.passphrase);
                ^

Error: error:0906D064:PEM routines:PEM_read_bio:bad base64 decode
    at Error (native)
    at Object.createSecureContext (_tls_common.js:85:17)
    at Server (_tls_wrap.js:776:25)
    at new Server (https.js:26:14)
    at Object.exports.createServer (https.js:47:10)
    at Object.<anonymous> (C:\Zerok\dev\centralizr\index.js:29:26)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)

As you may imagine, this is not even similar to what a real certificate, nor key file, looks like. They have the following content (there is no problem showing them since they are free, autosigned keys just for testing purposes):

enter image description here

enter image description here

So... what's wrong? Why does Node read these files as... a hex buffer? I don't really understand.

UPDATE:

Ok, thanks to Derek Brown, I can now see the content of both files, though I keep getting the same error: "bad base64 decode":

_tls_common.js:85
      c.context.setKey(options.key, options.passphrase);
                ^

Error: error:0906D064:PEM routines:PEM_read_bio:bad base64 decode
    at Error (native)
    at Object.createSecureContext (_tls_common.js:85:17)
    at Server (_tls_wrap.js:776:25)
    at new Server (https.js:26:14)
    at Object.exports.createServer (https.js:47:10)
    at Object.<anonymous> (C:\Zerok\dev\centralizr\index.js:29:26)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
halfer
  • 19,824
  • 17
  • 99
  • 186
Zerok
  • 1,323
  • 1
  • 24
  • 56

2 Answers2

3

readFileSync(...) returns a hex buffer if no encoding is specified. You should specify the encoding as utf8 (or whatever file encoding you are using) so that this doesn't happen:

const options = { key: fs.readFileSync("./key.pem", "utf8"), cert: fs.readFileSync("./cert.pem","utf8") };
Derek Brown
  • 4,232
  • 4
  • 27
  • 44
  • That fixed the first part, thank you! But I keep getting the other error... now I can see the content of both files properly, though it still throws the "bad base64 decode" error. – Zerok Oct 23 '17 at 15:34
  • 1
    Zerok have you double checked the content of your private key? It doesn't look long enough – Derek Brown Oct 23 '17 at 15:39
  • Actually, I'm not really sure if that's ok. That's the password I used in the certification creation, but maybe that's not what I have to put there? How can I retrieve the actual certificate key from StartSSL, do you know how to do it? I'm trying to look for more yet I can't find anything else – Zerok Oct 23 '17 at 15:43
  • 1
    It should be a `.pem` file that was generated when you created your request. – Derek Brown Oct 23 '17 at 15:46
  • 1
    These instructions may prove helpful. Never used StartSSL myself. https://gist.github.com/mgedmin/7124635 – Derek Brown Oct 23 '17 at 15:47
  • I've got two .pem files, one has my cert, and the other includes the intermediate certificates of StartSSL, but they didn't provide any sort of password. Will try the openssl thingy! – Zerok Oct 23 '17 at 15:51
  • 1
    It's not a password. You create a private key and a public key, and then use an outside certificate authority (StartSSL) to "sign" the public key, creating a new "signed" public key. – Derek Brown Oct 23 '17 at 15:56
  • 1
    The password is in addition to the private key. It is a way of encrypting the private key so that only authorized users in your machine have access to it. – Derek Brown Oct 23 '17 at 15:57
  • 1
    I would do some reading up on how SSL works conceptually before diving into those steps. That benefitted me a lot personally. – Derek Brown Oct 23 '17 at 15:58
0

This is because the PEM file is not being parsed. The actual certificate is between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----. Yet the key and cert which are console.logged begin with 2d 2d 2d 2d 2d which is hex for -----.

This code should fix that issue:

options = {
  key: fs.readFileSync("./key.pem").split("-----")[3], 
  cert: fs.readFileSync("./cert.pem").split("-----")[3]
}
nnsk
  • 93
  • 5