網站搜尋

javascript - 無法驗證葉節點簽章


我正在使用 node.js 的 request.js 來訪問一個 API。我收到了這個錯誤

[錯誤:無法驗證憑證簽章]

我所有的憑證都是準確且有效的,伺服器也沒問題。我用 Postman 發送了相同的請求。

request({
    "url": domain+"/api/orders/originator/"+id,
    "method": "GET",
    "headers":{
        "X-API-VERSION": 1,
        "X-API-KEY": key
    },
}, function(err, response, body){
    console.log(err);
    console.log(response);
    console.log(body);
});

這段程式碼只是作為可執行腳本運行,例如 node ./run_file.js,是這個原因嗎?它需要在伺服器上運行嗎?

答案#1

注意:以下內容具有危險性,將允許在客戶端與伺服器之間攔截並修改 API 內容。

這也有效

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';

答案#2

安全解決方案

與其關閉安全性,你可以將必要的憑證加入鏈中。首先從 npm 安裝 ssl-root-cas 套件:

npm install ssl-root-cas

此套件包含許多瀏覽器信任但 Node 不信任的中介憑證。

var sslRootCAs = require('ssl-root-cas/latest')
sslRootCAs.inject()

將會補上缺少的證書。更多資訊請見此處:

https://git.coolaj86.com/coolaj86/ssl-root-cas.js

答案#3

這不是應用程式的問題,而是憑證的問題,該憑證是由中介 CA 簽署的。如果你接受這個事實並且仍然想繼續,請將以下內容添加到請求選項中:

rejectUnauthorized: false

完整請求:

request({
    "rejectUnauthorized": false,
    "url": domain+"/api/orders/originator/"+id,
    "method": "GET",
    "headers":{
        "X-API-VERSION": 1,
        "X-API-KEY": key
    },
}, function(err, response, body){
    console.log(err);
    console.log(response);
    console.log(body);
});

答案#4

CoolAJ86 的解決方案是正確的,並且它不會像使用 rejectUnauthorized 或 NODE_TLS_REJECT_UNAUTHORIZED 禁用所有檢查那樣危及你的安全性。不過,你可能仍然需要明確地注入額外的 CA 證書。

我先嘗試了 ssl-root-cas 模組中包含的根憑證授權機構(CA):

require('ssl-root-cas/latest')
  .inject();

我仍然最終遇到了 UNABLE_TO_VERIFY_LEAF_SIGNATURE 錯誤。然後我通過 COMODO SSL 分析器找到了我連接的網站證書的簽發者,下載了該權威機構的證書,並嘗試只添加那一個:

require('ssl-root-cas/latest')
  .addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

我最終遇到了另一個錯誤:CERT_UNTRUSTED。最後,我注入了額外的根 CA 並包含了「我的」(顯然是中介)CA,這樣就成功了:

require('ssl-root-cas/latest')
  .inject()
  .addFile(__dirname + '/comodohigh-assurancesecureserverca.crt');

答案#5

對於 Create React App(這個錯誤也會發生在這裡,而且這個問題是 Google 的第一個搜尋結果),你可能在開發時使用 HTTPS=true npm start 和一個 proxy(在 package.json 中),它指向某個自簽名的 HTTPS API。

如果是這種情況,請考慮這樣更改 proxy:

"proxy": {
  "/api": {
    "target": "https://localhost:5001",
    "secure": false
  }
}

secure 決定 WebPack 代理是否檢查證書鏈,禁用它可以確保 API 自簽名證書不被驗證,從而讓你獲取數據。

答案#6

可能很想設置 rejectUnauthorized: false 或 process.env['NODE_TLS_REJECT_UNAUTHORIZED']='0';,但不要這麼做!這會讓你暴露於中間人攻擊的風險中。

其他答案是正確的,問題在於你的證書是「由中介 CA 簽署的」。這有一個簡單的解決方法,不需要像 ssl-root-cas 這樣的第三方庫,也不需要向 Node 注入任何額外的 CA。

大多數在 Node 的 https 客戶端都支援允許你為每個請求指定 CA 的選項,這將解決 UNABLE_TO_VERIFY_LEAF_SIGNATURE。這裡是一個使用 Node 內建 https 模組的簡單範例。

import https from 'https';

const options = {
  host: '<your host>',
  defaultPort: 443,
  path: '<your path>',
  // assuming the bundle file is co-located with this file
  ca: readFileSync(__dirname + '/<your bundle file>.ca-bundle'),
  headers: {
    'content-type': 'application/json',
  }
};
https.get(options, res => {
  // do whatever you need to do
})

不過,如果你可以在你的主機伺服器上配置 SSL 設定,最好的解決方案是將中繼證書添加到你的主機提供商。這樣客戶端請求者就不需要指定 CA,因為它已包含在伺服器本身。我個人使用 Namecheap + Heroku。對我來說的技巧是使用 cat yourcertificate.crt bundle.ca-bundle > server.crt 創建一個 .crt 文件。然後我打開這個文件,在第一個證書之後添加了一個換行符。你可以在這裡閱讀更多資訊

https://www.namecheap.com/support/knowledgebase/article.aspx/10050/33/在Heroku上安裝SSL憑證