How to create .pem files for https web server - node.js

I'm using the Express framework in Node.js to create a web server. I want to use ssl for the web server's connection.
The code to create the https web server is as below.
var app = express.createServer({
key: fs.readFileSync('./conf/key.pem'),
cert: fs.readFileSync('./conf/cert.pem')
});
module.exports = app;
Question: How to create the key.pem and cert.pem required by express?

The two files you need are a PEM encoded SSL certificate and private key. PEM encoded certs and keys are Base64 encoded text with start/end delimiters that look like -----BEGIN RSA PRIVATE KEY----- or similar.
To create an SSL certificate you first need to generate a private key and a certificate signing request, or CSR (which also contains your public key).You can do this in a variety of ways, but here's how in OpenSSL.
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem
This will cause you to enter an interactive prompt to generate a 2048-bit RSA private key and a CSR that has all the information you choose to enter at the prompts. (Common Name is a legacy location where domain names used to go, but modern browsers require an extension called SubjectAlternativeName now. However, when submitting to a CA they will put CN values in SAN) Once you've done this you would normally submit this CSR to a trusted certificate authority and once they've validated your request you would receive a certificate.
If you don't care about your certificate being trusted (usually the case for development purposes) you can just create a self-signed certificate. To do this, we can use almost the same line, but we'll pass some extra parameters. The interactive prompt doesn't support Subject Alternative Name (SAN), which is required in most modern clients, so we pass it on the CLI via the -addext flag. You'll need to change mydnsname.com to the right name for your uses. Be sure to keep DNS: though!
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem -addext "subjectAltName = DNS:mydnsname.com"
This will give you a cert (valid for 10 years) and key pair that you can use in the code snippet you posted.

Just follow this procedure :
create the folder where you want to store your key & certificate :
mkdir conf
go to that directory :
cd conf
grab this ca.cnf file to use as a configuration shortcut :
wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/ca.cnf
create a new certificate authority using this configuration :
openssl req -new -x509 -days 9999 -config ca.cnf -keyout ca-key.pem -out ca-cert.pem
now that we have our certificate authority in ca-key.pem and ca-cert.pem, let's generate a private key for the server :
openssl genrsa -out key.pem 4096
grab this server.cnf file to use as a configuration shortcut :
wget https://raw.githubusercontent.com/anders94/https-authorized-clients/master/keys/server.cnf
generate the certificate signing request using this configuration :
openssl req -new -config server.cnf -key key.pem -out csr.pem
sign the request :
openssl x509 -req -extfile server.cnf -days 999 -passin "pass:password" -in csr.pem -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem
I found this procedure here, along with more information on how to use these certificates.

An alternative is to generate the certificates with the pem library using the createCertificate method of the class.
The process would be as follows:
Install openssl in your system if not there already, for instance for windows 10 the a compiled version of the sources (seems like the most open one) can be found here: https://curl.se/windows/ the explanations of how it is compiled and safeguarded are here: https://wiki.openssl.org/index.php/Binaries. For the source https://www.openssl.org/community/binaries.html
For windows, you may want to add the diretory of the openssl.bin file to the system environment path variable (https://www.architectryan.com/2018/08/31/how-to-change-environment-variables-on-windows-10/) or pass the location of the file to the PEM library.
Instal pem using (documentation here: https://github.com/Dexus/pem
npm i pem
at the command line at the root of the server.
From the documentation you can see that a simple https server with the keys can be created simply by:
const https = require('https')
const pem = require('pem')
pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => {
if (err) {
throw err
}
https.createServer({ key: keys.clientKey, cert: keys.certificate }, (req, res) => {
res.end('o hai!')
}).listen(443)
})
or using express
npm i express
at the command line at the root of the server):
const https = require('https')
const pem = require('pem')
const express = require('express')
pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => {
if (err) {
throw err
}
const app = express()
app.get('/', (req, res) => {
res.send('o hai!')
})
https.createServer({ key: keys.clientKey, cert: keys.certificate }, app).listen(443)
})
Just changed the var for const as appropiate, and functions for arrow functions

Related

ASP.NET Core 6 ReactJS Web App on Linux has issues with IDX10634: Unable to create the SignatureProvider

I have deployed an ASP.NET 6 solution based on the ASP.NET 6 ReactJS template into a Linux CentOS/Apache hosting environment.
According to the error message provided below, It seems I need to alter the algorithm for the signature provider, yet I am at a loss of how exactly to do this.
System.NotSupportedException: IDX10634: Unable to create the SignatureProvider.
Algorithm: 'RS256', SecurityKey: 'Microsoft.IdentityModel.Tokens.X509SecurityKey, KeyId: 'xxxxxxxxxxxx', InternalId: 'xxxxxxx'.' is not supported. The list of supported algorithms is available here: https://aka.ms/IdentityModel/supported-algorithms
I have found several FAQs indicating to use ECDSA or similar instead, but no real examples of how exactly to implement this within my type of solution with examples of modifications in Program.cs or similar.
I would appreciate any tips of thoughts on this!
Thanks in advance!
You can use OpenSSL to create your own ECDSA key using:
#Create P256 ECDSA Private key
openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -aes256 -out p256-private.pem
# Optionally, if you want to extract the public key:
openssl ec -in p256-private.pem -pubout -out p256-public.pe
# Create certificat file
openssl req -new -x509 -key p256-private-key.pem -days 365 -subj "/CN=MyP256Cert" -out p256-cert.crt
# Crete the PFX file
openssl req -new -x509 -key p256-private-key.pem -days 365 -subj "/CN=MyP256Cert" -out p256-cert.crt
Then you can load it in C# using:
var ecdsaCert = new X509Certificate2("es256.pfx", "password");
SecurityKey ecdsaPrivateKey = new ECDsaSecurityKey(ecdsaCert.GetECDsaPrivateKey());
You can add it to IdentityServer using something like this:
// Add ES256 (ECDSA using P-256 and SHA-256)
builder.AddSigningCredential(GetECDsaPrivateKey(p256Cert), IdentityServerConstants.ECDsaSigningAlgorithm.ES256);

net::ERR_CERT_AUTHORITY_INVALID (React with Node)

Please Help, I'm in a big trouble.
Actually, I'm learning Full Stack Web Development with React on Coursera.
I created the private key and certificate by typing the following at the prompt:
openssl genrsa 1024 > private.key
openssl req -new -key private.key -out cert.csr
openssl x509 -req -in cert.csr -signkey private.key -out certificate.pem
These above commands created 3 files on the given location :- private.key, certificate.pem and cert.csr
And then i included this in www file:-
var options = {
key: fs.readFileSync(__dirname+'/private.key'),
cert: fs.readFileSync(__dirname+'/certificate.pem')
};
var secureServer = https.createServer(options,app);
After Integrating both React Client and Server, i was able to run my react app on Browser.
But when i tried to access the React app using the Network IP address, it stops fetching data from server and on console i found this error message - net::ERR_CERT_AUTHORITY_INVALID
Please help, As i said i'm learning. I have no idea about this.

how to convert ssl private-key.txt to private.key extension

I got pvt-key.txt, certificate.crt and bundle.crt files from godaddy.
I am setting ssl for node js backend using https options
var httpsoptions = {
key: fs.readFileSync("pvt-key.txt"),
cert: fs.readFileSync("certificate.crt")
};
but it is not working.
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
I also converted .txt to .pem but there is same error. if I generate key from this command
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout privateKey2.key -out certificate2.crt
then it works. I think there should be .key extension instead of .pem or .txt. Please help me to convert file into .key extension. Thank you in advance.
The extension of the file doesn't matter so much, but the contents of the file do. I suspect node wants a PEM encoded private key. You can convert a DER encoded private key to a PEM one like this:
openssl rsa -in pvt-key.txt -outform pem -out pvt-key.key
In order to accomplish this, #vcsjones provided the solution I was able to use.
openssl rsa -in pvt-key.txt -outform pem -out pvt-key.key
But, I got the same error as others:
Expecting: ANY PRIVATE KEY.
My fix was found in https://stackoverflow.com/a/54026652.
Open the key file in Notepad++ and verify the encoding. If it says UTF-8-BOM then change it to UTF-8. Save the file and try again.

NodeJS - I have a .key file with password and I need to get the .pem file with RSA PKCS8 method

I have a .key file with password and I need to get the .pem file with RSA PKCS8 method with NodeJS function.
The command I use to do it with OpenSSL is the following
How can I do this in NodeJS???
openssl pkcs8 -inform DER -in file.key -out file.pem -passin pass:passwordkey
Let's say for example you have a key.pem file in a https folder and you want it as a parameter for your server options. You can get it via fs.readFileSync. Hope this helps.
const path = require("path");
server.httpsServerOptions = {
key: fs.readFileSync(path.join(_dirName, "./../https/key.pem"))
};

SOAP request in Node using SSL

Recently, I've been working with SOAP requests.
I've managed to use the node-soap module to be able to send successful requests to http services. However, now I want to use it to send a request to an external https web service.
I have managed to send SSL requests using a .cer file with cUrl. But when trying this in the node.js code, I am getting errors. From what I have read (see ClientSSLSecurity on the node-soap module), I need a key (in .key format) and a certificate (in .pem format). I do not know whether this requires a private key or not? I have managed to extract a public key from my .cer file.
I have tried the below code:
var createSoapClient = function (){
soap.createClient(url, function(err,client){
client.setSecurity(new soap.ClientSSLSecurity(
'mycert.cer',
'pubkey.key'
));
if(err)
console.error(err);
else {
client.MyOperation(args,function(err,response){
if(err){
console.error(err);
}
else{
console.log(response);
}
})
}
});
}
however, this results in the below error message:
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
What am I missing? Is it a private key?
Thank you!
According to package found on npm, regarding ClientSSLSecurity :
https://www.npmjs.com/package/axl-node-soap
https://www.npmjs.com/package/soap-x509
https://www.npmjs.com/package/strong-soap#clientsslsecurity
https://www.npmjs.com/package/soap#clientsslsecurity
I assume that you've pass wrong argument to ClientSSLSecurity. It seems to take the key then the certificate, you're passing the certificate then the key.
Try to do something like this :
client.setSecurity(new soap.ClientSSLSecurity(
'pubkey.key',
'mycert.cer'
));
Which package are you using ?
You're couple key/cert is probably wrong
Try to regenerate the certificate :
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem
openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out server.crt
then pass key.pem as the key and server.crt as the certificate.

Resources