Node.js https pem 错误:routines:PEM_read_bio:no start line

Posted

技术标签:

【中文标题】Node.js https pem 错误:routines:PEM_read_bio:no start line【英文标题】:Node.js https pem error: 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 文件,因此非常感谢任何帮助。

谢谢

【问题讨论】:

你修复了这个错误吗? 【参考方案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】:

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

打开终端

    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 和 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 遵循以下步骤:

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

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

来源: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

$ 输入私钥密码...`

然后就可以了!

【讨论】:

以上是关于Node.js https pem 错误:routines:PEM_read_bio:no start line的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 搭建 https 协议 服务器

如何为 https Web 服务器创建 .pem 文件

在 Node.js 中使用公钥加密数据

node.js的路由

在 Node.js 中使用 async/await 正确处理错误

尝试实现 socket.io 通信时收到 GET 400。 Node.js、ELB、Route 53、CloudFront 和 s3