【问题标题】:Node.js https pem error: routines:PEM_read_bio:no start lineNode.js https pem 错误:routines:PEM_read_bio:no start line
【发布时间】:2014-04-30 07:49:35
【问题描述】:

我现在正在使用 node.js 处理登录表单,我尝试使用

创建 pem 密钥和 csr
openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem

但是我在运行 node server.js 时遇到错误

这是我的 server.js

var http = require('http'),
    express = require('express'),
UserServer = require('./lib/user-server');

var https = require('https');
var fs = require('fs');

var options = {
  key: fs.readFileSync('./key.pem', 'utf8'),
  cert: fs.readFileSync('./csr.pem', 'utf8')
};

var app = express();

app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

var httpserver = http.createServer(app).listen('3004', '127.0.0.1');
var https_server = https.createServer(options, app).listen('3005', '127.0.0.1');
UserServer.listen(https_server);

这是错误

crypto.js:104
  if (options.cert) c.context.setCert(options.cert);
                          ^
Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
    at Object.exports.createCredentials (crypto.js:104:31)
    at Server (tls.js:1107:28)
    at new Server (https.js:35:14)
    at Object.exports.createServer (https.js:54:10)

我试着跑了

openssl x509 -text -inform DER -in key.pem

它给了

unable to load certificate
140735208206812:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1319:
140735208206812:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:381:Type=X509

我不确定该错误是什么意思,因为我的加密文件已经是 .pem 文件,因此非常感谢任何帮助。

谢谢

【问题讨论】:

  • 你修复了这个错误吗?

标签: node.js security login https pem


【解决方案1】:

您可能使用了错误的证书文件,您需要做的是生成一个自签名证书,可以如下完成

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

然后使用server.crt

   var options = {
      key: fs.readFileSync('./key.pem', 'utf8'),
      cert: fs.readFileSync('./server.crt', 'utf8')
   };

【讨论】:

  • 我试过这个,但是当我重新加载我的服务时,我收到一个错误“EACCES,权限被拒绝”
  • 节点进程可能无权读取证书或绑定端口。如果您在 linux 上,请尝试通过 sudo 运行。
  • 如果您正在使用 express 或裸 nodejs 应用程序,通常它会在您的 app.js 文件中。
  • 您确定./csr.pemkey 选项的正确文件吗?它给了我同样的错误,但是当我将密钥切换到./key.pem 时,一切正常。似乎对您的原始答案所做的最后一次编辑是错误的。
  • (请注意,Michael 在此处的评论已被注意,并且答案已被编辑,现在是正确的.....对于其他人在评论和答案之间来回查看以试图弄清楚这一点。)
【解决方案2】:

我通过编写以下代码消除了这个错误

打开终端

  1. openssl req -newkey rsa:2048 -new -nodes -keyout key.pem -out csr.pem

  2. openssl x509 -req -days 365 -in csr.pem -signkey key.pem -out server.crt

现在使用 server.crt 和 key.pem 文件

app.js 或 server.js 文件

var https = require('https');
var https_options = {
  key: fs.readFileSync('key.pem', 'utf8'),
  cert: fs.readFileSync('server.crt', 'utf8')
};

var server = https.createServer(https_options, app).listen(PORT);
console.log('HTTPS Server listening on %s:%s', HOST, PORT);

它可以工作,但证书不受信任。您可以在图像文件中查看图像。

【讨论】:

  • 这是正常的。 Chrome 不识别自签名证书,只识别来自它信任的 CA 的证书。您有三种不同的解决方案: 1. chrome://flags -> 允许来自 localhost 的无效证书 2. 将您的证书添加到您的浏览器,以便它接受这个新的 CA 3. 使用第三方服务,如 LetsEncrypt
【解决方案3】:

面临同样的问题在我的情况下,我将 cert 的选项参数更改为 pfx 并删除了 utf8 编码。

之前:

var options = {
    hostname : 'localhost',
    path : '/',
    method : 'POST',
    cert: fs.readFileSync(testCert, 'utf8'),
    passphrase:passphrase,
    agent:false,
    rejectUnauthorized:false
};

之后:

var options = {
    hostname : 'localhost',
    path : '/',
    method : 'POST',
    pfx: fs.readFileSync(testCert),
    passphrase:passphrase,
    agent:false,
    rejectUnauthorized:false
};

【讨论】:

  • 我收到 wrong tagheader too long 错误 — 有什么问题?
【解决方案4】:

对我来说,问题是我交换了密钥和证书。

var options = {
   key: fs.readFileSync('/etc/letsencrypt/live/mysite.com/privkey.pem'),
   cert: fs.readFileSync('/etc/letsencrypt/live/mysite.com/fullchain.pem'),
   ca: fs.readFileSync('/etc/letsencrypt/live/mysite.com/chain.pem')
};

编辑

更完整的示例(可能功能不完整)

Server.js

    var fs = require('fs');

    var sessionKey = 'ai_session:';
    var memcachedAuth = require('memcached-auth');

    var clients = {};
    var users = {};

    var options = {
      key: fs.readFileSync('/etc/letsencrypt/live/somesite.com/privkey.pem'),
      cert: fs.readFileSync('/etc/letsencrypt/live/somesite.com/fullchain.pem'),
      ca: fs.readFileSync('/etc/letsencrypt/live/somesite.com/chain.pem')
    };

    var origins = 'https://www.somesite.com:*';
    var https = require('https').createServer(options,function(req,res){

        // Set CORS headers
        res.setHeader('Access-Control-Allow-Origin', origins);
        res.setHeader('Access-Control-Request-Method', '*');
        res.setHeader('Access-Control-Allow-Methods', 'OPTIONS, GET');
        res.setHeader('Access-Control-Allow-Headers', '*');

    });

    var io = require('socket.io')(https);
    https.listen(3000);

    io.sockets.on('connection', function(socket){

      socket.on('auth', function(data){

          var session_id = sessionKey+data.token;
          memcachedAuth.is_logged_in(session_id).then( (response) => {

          if(response.is_logged_in){

              // user is logged in
              socket.emit('is_logged_in', true);

              messenger.addUser(socket); 

              // dynamic room
              socket.on('room', function(room){
             socket.join(room);
             console.log('joing room '+room);
              });

              socket.on('message', function(data){
              messenger.receive(data.message_data);                 
              });
          }else{
              // Not logged in
              socket.emit('is_logged_in', false);
          }
          }).catch( (error) => {
          console.log(error);
          });

      });


    });


    var messenger = {
        socket: (socket)=>{
          return socket;  
        },
        subscribe: (room)=>{

        },
        unsubscribe: (room)=>{

        },
        send: (data)=>{

        },
        receive: (data)=>{
        console.log(data);
          //connected
          if (clients[data.user_name]){
            console.log('user');
          }    
        },
        addUser: (socket)=>{
        socket.on('add-user', function(data){
            clients[data] = {
              "socket": socket.id
            };
            console.log('Adding User:' + data);
            console.log(clients);
        });          
        },
        private: (socket)=>{
        // Not working yet...
        socket.on('message', function(data){

            console.log("Sending: " + data + " to " + data.user_name);

            if (clients[data.user_name]){
              io.sockets.connected[clients[data.user_name].socket].emit("response", data);
            } else {
              console.log("User does not exist: " + data.user_name); 
            }
        });           
        },
        disconnect:()=>{
        //Removing the socket on disconnect
        socket.on('disconnect', function() {
         for(var name in clients) {
           if(clients[name].socket === socket.id) {
             delete clients[name];
             break;
           }
         }  
        });         
        }
    }

如果有人感兴趣,我在 github 上创建了一个 repo,包括上述代码的更完整版本:https://github.com/snowballrandom/Memcached-Auth

【讨论】:

  • 哪个文件是哪个?
  • @toto_tico privkey.pem => key, fullchain.pem => 你的公共证书,chain.pem => ca(即证书授权文件)
  • 如果我使用 openssl 签署自己的证书,以下内容是否正确? openssl req -newkey rsa:2048 -new -nodes -keyout privkey.pem -out fullchain.pemopenssl x509 -req -days 365 -in fullchain.pem -signkey privkey.pem -out chain.pem
  • 是的,看起来不错,如果您在 linux 中,所有选项的命令行上都应该有帮助部分。
  • 你是救生员!我也把它们交换了。
【解决方案5】:

实际上我也收到了同样的错误信息。

问题是我在配置对象中交换了keycert 文件。

【讨论】:

    【解决方案6】:

    对我来说,在尝试了上述所有解决方案之后,它最终成为了与编码相关的问题。简而言之,我的密钥是使用“带有 BOM 的 UTF-8”编码的。它应该是 UTF-8。

    要修复它,至少使用 VS Code 遵循以下步骤:

    1. 打开文件并单击状态栏(底部)的编码按钮,然后选择“使用编码保存”。
    2. 选择 UTF-8。
    3. 然后再次尝试使用证书。

    我想您可以使用其他支持以正确编码保存的编辑器。

    来源:error:0906d06c:pem routines:pem_read_bio:no start line, when importing godaddy SSL certificate

    P.D 在使用 fs.readFileSync 函数加载文件时,我不需要将 encoding 设置为 utf-8 选项。

    希望这对某人有所帮助!

    【讨论】:

      【解决方案7】:

      我遇到了这样的问题。

      问题是我在开头添加了没有'-----BEGIN PUBLIC KEY-----'的公钥并且没有'-----END PUBLIC KEY----- '。

      所以它会导致错误。

      最初,我的公钥是这样的:

      -----BEGIN PUBLIC KEY-----
      WnsbGUXbb0GbJSCwCBAhrzT0s2KMRyqqS7QBiIG7t3H2Qtmde6UoUIcTTPJgv71
      ......
      oNLcaK2wKKyRdcROK7ZTSCSMsJpAFOY
      -----END PUBLIC KEY-----
      

      但我只使用了这部分:

      WnsbGUXb+b0GbJSCwCBAhrzT0s2KMRyqqS7QBiIG7t3H2Qtmde6UoUIcTTPJgv71
      ......
      oNLcaK2w+KKyRdcROK7ZTSCSMsJpAFOY
      

      【讨论】:

      • 您发布的内容是有道理的,我对此很熟悉 - 它是否正确解决了所述问题?
      【解决方案8】:

      我猜这是因为您的 nodejs 证书已过期。输入这一行:
      npm set registry http://registry.npmjs.org/
      然后用 npm install 再试一次。这实际上解决了我的问题。

      【讨论】:

        【解决方案9】:

        对我来说,解决方案是替换 \\n(以一种奇怪的方式格式化为密钥)代替 \n

        更换你的 key: <private or public key>key: (<private or public key>).replace(new RegExp("\\\\n", "\g"), "\n")

        【讨论】:

          【解决方案10】:

          如果您使用的是 Windows,则应确保证书文件 csr.pem 和 key.pem 没有 unix 样式的行尾。 Openssl 将生成带有 unix 样式行结尾的密钥文件。您可以使用 unix2dos 等实用程序或 notepad++ 等文本编辑器将这些文件转换为 dos 格式

          【讨论】:

            【解决方案11】:

            如果你记录了

            var options = {
              key: fs.readFileSync('./key.pem', 'utf8'),
              cert: fs.readFileSync('./csr.pem', 'utf8')
            };
            

            您可能会注意到由于编码不当而导致出现无效字符。

            【讨论】:

              【解决方案12】:

              损坏的证书和/或密钥文件

              对我来说,这只是损坏的文件。我从 GitHub PullRequest 网页复制了内容,我想我在某处或其他地方添加了一个额外的空间......一旦我抓住了原始的东西并替换了文件,它就起作用了。

              【讨论】:

                【解决方案13】:

                生成具有特定到期日期或无限(XXX)到期时间的私钥和服务器证书并自行签名。

                $ openssl req -x509 -sha256 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX

                $ 输入私钥密码...`

                然后就可以了!

                【讨论】:

                  猜你喜欢
                  • 2019-10-16
                  • 2016-09-04
                  • 1970-01-01
                  • 2020-09-22
                  • 1970-01-01
                  • 2018-11-01
                  • 2020-07-16
                  • 2020-11-07
                  • 2020-10-30
                  相关资源
                  最近更新 更多