How to fix 'Hostname/IP does not match certificate's altnames' - node.js

I have a problem when I run get a response for service. There are two services. For the first service, it's working perfectly but in the second I have issue "Error [ERR_TLS_CERT_ALTNAME_INVALID]: Hostname/IP does not match certificate's altnames: Cert is empty". When I used Postman with certificates its works perfectly. What should I set or implement to make it works?​
I tried using: checkServerIdentity, rejectUnauthorized: true.
let options = {
hostname: 'ws.aaa.bbb.nn',
path: '/api',
method: 'GET',
key: fs.readFileSync('/private.crt'),
cert: fs.readFileSync('/public.crt'),
passphrase: '***'
};
const req = https.request(options, (res) => {
let body = '';
res.on('data', (chunk)=> {
body += chunk;
console.log(body)
});
});
Should be status code 200.

Seems you got a bad certificate.
Get a correct one or just turn the SSL certificate verification off.

I had the same problem, Just try to set Authorization Type to "Inherit auth from parent".

Related

fetchError: unable to verify the self-signed certificate along with net::ERR_CERT_AUTHORITY_INVALID with put method

I am using a next js node server as my app. And a ngnix as my https server with self-signed certificate in which my API node server is at behind.
But I am getting a self-signed certificate error.
So, in my next js , I will contact the https server either by fetch and axios. for example.
Is there a easy way on how to get ride of it without buying SSL from real CA?
What I have tried:
This problem couldn't be by pass thru chrome insecure content enabling since it is a server error.
I am guessing this could be achieved from either setting node server / fetch or axios. But I am so new on this kind of problem.
second update
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
works to get rid of the fetch error:
But now it shown this error with put method:
net::ERR_CERT_AUTHORITY_INVALID
What I have done is to put process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; on every api call.
For example
try {
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
const res = await axios.put(url);
} catch (error) {
console.log(error);
}
I am still looking for a solution.
Try adding httpsAgent in your fetch call
const https = require('https');
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
const response = await fetch("https://localhost/api", {
// Adding method type
method: "POST",
// Adding body or contents to send
body: JSON.stringify(
{data:"data"}),
// Adding headers to the request
headers: {
"Content-type": "application/json; charset=UTF-8"
},
agent: httpsAgent,
})
It worked for me

Nodejs Axios Error: Hostname/IP doesn't match certificate's altnames: "Host: (URL). is not in the cert's altnames: DNS:*.sa-east-1.es.amazonaws.com"

I'm trying to request an API from a third party server from a shared hosting server, so i don't have root access, and receive this error, but when i try it from my insomnia, it works normally, aparently its something due to proxy or certificates. Already tried using httpsAgent: new https.Agent({ rejectUnauthorized: false }) in axios request options, and tried NODE_TLS_REJECT_UNAUTHORIZED=0, but no success. I didn't paste cert and server info info but if it's necessary i can share it. That's how i'm making the request:
async appInfo(){
var config = {
method: 'get',
url: `${this.url}/api/v2/me/shipment/app-settings`,
headers: {
'Accept': 'application/json',
'Authorization':`Bearer ${this.bearer}`,
'User-Agent': this.user_agent
}
};
var response = await axios(config)
console.log(JSON.stringify(response.data));
}
i don't know if you fixed it already, but i will answer anyways. It might help others. Here's the solution i found here: https://github.com/axios/axios/issues/1650
Seeing your code, you should have the agent config outside of the header. Like that:
// At instance level
const instance = axios.create({
httpsAgent: new https.Agent({
rejectUnauthorized: false
})
});
instance.get('https://something.com/foo');
// At request level
const agent = new https.Agent({
rejectUnauthorized: false
});
axios.get('https://something.com/foo', { httpsAgent: agent });
Warning: It may be a security failure, only use it if you really trust where you sharing the data.
Cheers.

Node-fetch: Disable SSL verification

I have the following code, which is run from a express server:
import fetch from 'node-fetch';
let formBody = [];
const dataLogin = {
'username': 'myUser',
'password': 'myPassword'
};
for (let p in dataLogin) {
let encodedKey = encodeURIComponent(p);
let encodedValue = encodeURIComponent(dataLogin[p]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
const url = 'https://external-login-api.com';
return fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': formBody.length
},
body: formBody
});
When I run the code I get the following error, despite being able to run the request in Postman with no problems.
{"message":"request to https://external-login-api.com failed, reason: write EPROTO 7316:error:141A318A:SSL routines:tls_process_ske_dhe:dh key too small:openssl\ssl\statem\statem_clnt.c:1472:\n","type":"system","errno":"EPROTO","code":"EPROTO"}
How do I disable SSL verification for this request?
The other way to do is to set your own agent to the fetch call.
const fetch = require('node-fetch');
const https = require('https');
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
const response = await fetch(url, {
method: 'POST',
headers: headers,
body: body,
agent: httpsAgent,
});
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
Will ensure you ignore any rejected TLS certificates, or you can set this as an environment variable when running your node service. However this will likely not help, and is probably a bad idea. The SSL error is not because the certificate is invalid (such as a self signed certificate) but instead because of a weak Diffie-Hellman key in the SSL/TLS configuration.
If this a service you're hosting you should look at correcting and improving your TLS/SSL cyphers. See this answer for more information.
The important part is:
You should use 2048-bit Diffie-Hellman groups or larger. You should
not be using 512-bit or 1024-bit Diffie-Hellman groups.
If this is a third party service, you should consider contacting them or using a different service as they are leaving themselves open to the Logjam attack which is also discussed in the answer linked above.

Node.js: access the client certificate

I'm working on a Node.js app that we will call "server A" where users have to provide a client certificate in order to access services.
Simplified example:
/** server setup **/
var serverOptions = {
key: fs.readFileSync('certs/server.key'),
cert: fs.readFileSync('certs/server.crt'),
ca: [fs.readFileSync('certs/ca.crt'), fs.readFileSync('certs/bar.cer'), fs.readFileSync('certs/foo.cer')],
requestCert: true
};
https.createServer(serverOptions, app).listen(SERVER_PORT, '', null, function () {
var host = this.address().address;
var port = this.address().port;
console.log('listening at http://%s:%s', host, port);
});
Everything works as expected, the following code prints the details of the client certificate.
app.get('/', function (req, res) {
/*** Dump ***/
res.contentType('application/json');
res.send(util.inspect(req.socket.getPeerCertificate(true), {colors: true}));
});
However, I would like to be able to use this client certificate obtained in serverA, to make a request to another server called "server B".
options = {
hostname: 'localhost',
port: '3010',
path: '/',
method: 'POST',
headers: {
'Content-Type': 'text/xml;charset=UTF-8',
'Content-Length': serverResponse.length,
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
},
cert: clientCertificate
};
var req = https.request(options, function (res) {
console.log('statusCode: ', res.statusCode);
console.log('headers: ', res.headers);
res.on('data', function(d) {
callback(d);
});
});
The problem is that I have not found a way to get a proper X509 certificate with the getPeerCertificate function, which returns a "custom" object representation of the certificate.
As described in the official documentation, the cert parameter must be provided with the following data :
Public x509 certificate to use. Default null.
Is there a way to get the client certificate in the correct format for that purpose?
I had the same problem and saw your question with no answers, so I'm coming back to post my solution.
The certificate object has a raw field which contains the certificate data you want in byte form. To get it in X509 format, just convert it to base64. So the code you're looking for is:
req.socket.getPeerCertificate(true).raw.toString('base64');
Hope that helps!

Verify ssl certificate in nodejs

How can I verify SSL certificate on https of given domain by NodeJS?
I need to know if user open this like is it trusted or should add it as exception?
--
I think this code should raise error during unsigned or selfsigned certificate.
var https = require('https');
var options = {
host: 'daarkoob.ir',
port: 2222,
path: '/',
method: 'GET',
rejectUnauthorized:true
};
var req = https.request(options, function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
});
req.end();
req.on('error', function(e) {
console.error(e);
});
https://daarkoob.ir:2222 is self signed certificated,so above code should raise error during surfing.but nothing happened.
From the documentation:
rejectUnauthorized: If true, the server certificate is verified against
the list of supplied CAs. An 'error' event is emitted if verification
fails. Verification happens at the connection level, before the HTTP
request is sent. Default true.
I guess that you need to specify a list of CA or the option is ignored.

Resources