JS在线运行

版本:

所属目录
点击了解高性能代码运行API
运行结果
教程手册
代码仓库
极速运行
终端运行
图形+终端

                        
以下是用户最新保存的代码
check in balalal 发布于:2025-04-26 17:54 最近一次给学姐的代码 发布于:2025-04-26 13:13 JS AES128加解密 发布于:2025-04-21 13:44 最小矩阵宽度(从第一列开始一列列加,直到判断子矩阵内包含数组的所有元素) 发布于:2025-04-16 19:10 最小交付时间(二分+回溯:先将数组排序,最小值start=Math.max(arr),最大值end = arr.reduce,回溯中创建一个新的工人数组,每次遍历数组时将数组中的每一个元素都尝试分配给worker[i]) 发布于:2025-04-16 18:53 阿里巴巴找黄金宝箱Ⅳ(单调栈:栈中存储单调递减的元素的集合,当找到比栈顶元素大的元素时,循环出栈直到栈顶元素不小于当前元素) 发布于:2025-04-15 17:47 找出经过特定点的路径长度(dfs+回溯) 发布于:2025-04-14 16:32 计算最接近的数(1.输入处理;2.对数组进行深拷贝,然后对新数组进行排序,之后在进行后续操作) 发布于:2025-04-14 15:11 MELON的难题(01背包问题:先判断数组和是否为偶数,如果为偶数直接输出-1,target=sum/2 状态转移方程dp[i]=Math.min(dp[i],dp[i-1]+1) 发布于:2025-04-11 17:29 简易内存池(模拟,双指针) 发布于:2025-04-11 17:12 通过软盘拷贝文件 这是一个典型的 0-1 背包问题的变体: 问题描述: 有一个容量为 1.44MB(1474560字节)的软盘 每个块大小为 512 字节 需要在有限容量内存储最大的文件字节总和 关键点: 文件大小以字节为单位 存储空间以块为单位 即使文件不足一个块,也要占用整个块的空间 动态规划解析: 状态定义:dp[i] 表示使用 i 个块时能存储的最大字节数 状态转移:对每个文件,可以选择放入或不放入 约束条件:总块数不能超过软盘容量 时间复杂度:O(n maxSize),其中: n 是文件数量 maxSize 是软盘最大块数(约2880块) 发布于:2025-04-11 16:39 正整数到excel编号之间的转换(对num先进行取余操作,取余之后的值就是字母a往后的偏移量,letter=String.fromCharCode('a'.charCodeAt(0)+remain),将这个字母放到结果队首,然后对num进行整除,循环直到num为0) 发布于:2025-04-10 17:46 最少交换次数(滑动窗口:先算出整个数组内<k的个数,作为窗口大小,然后再算出0-window内>=k的个数,作为res的初始值,然后滑动窗口,当arr[left]>=k时,res--,当arr[right]>=k时,res++) 发布于:2025-04-10 17:40 TLV解析 Ⅱ(字符串操作) 发布于:2025-04-10 16:24 最少有多少个小朋友了(相同的数字的个数/(相同个数+1)*(相同个数+1)) 发布于:2025-04-10 15:11 硬件产品销售方案(回溯 backtrack(path,val,sum)=>) 发布于:2025-04-09 18:40 猴子爬山(动态规划:状态转义方程dp[i]=dp[i-1]+dp[i-3]) 发布于:2025-04-09 18:14 检测工具代码 发布于:2025-04-09 18:03 检查是否存在满足条件的数字组合)(双指针,然后多重判断) 发布于:2025-04-09 17:45 阿里巴巴找黄金宝箱III(遍历数组,用map储存arr[i]上一次出现的下标,如果当前下标位置i-map.get(i)<=k,直接输出left) 发布于:2025-04-09 17:07 阿里巴巴找黄金宝箱II(数组排序,每次都找最大的减) 发布于:2025-04-09 16:48 全量和已占用字符集(字符串操作) 发布于:2025-04-09 16:34 微服务的集成测试(dfs:当扫描到第i行的第i个元素为1时,就递归dfs,sum+=Math.max(max,dfs(j))) 发布于:2025-04-09 16:25 经典屏保问题(判断是否反向:右下角坐标值为(x+50,y+25),当右下角撞到下面或者右边的墙时,就将x轴/y轴的移动方向反向,左上角同理。) 发布于:2025-04-08 18:37 阿里巴巴找黄金宝箱(I)(左右数组的和,如果左右数组的和相等,就输出) 发布于:2025-04-08 16:57 告警抑制(Map) 发布于:2025-04-08 16:35 过滤组合字符串(全排列:回溯) 发布于:2025-04-03 18:56 分糖果(判断是否为偶数,如果为偶数,操作次数+1,n=n/2;如果为奇数,判断(n+1)/2是否为偶数,如果是偶数,n=n+1,res++,否则n=n-1,res++) 发布于:2025-04-03 18:24 查找接口成功率最优时间段(用前缀和求出[left,right]区间的和,然后求平均值,和输入值比较,如果<=平均值,就移动右指针,如果>平均值,说明当前位置有一个当前最大的区间,比较这个区间是否为最大,如果不是则继续,如果是最大,则更新res结果;如果和当前的i最大值一样,那就将两个都放入到res中。最后,如果left和right不相等,说明最后一个窗口没处理完成,需要单独处理) 发布于:2025-04-03 18:15 游戏分组(dfs // 深度优先搜索函数 // 参数说明: // idx: 当前考虑的数组索引 // level: 当前已选择的数字个数 // subSum: 当前已选择数字的和 // totalSum: 整个数组的总和) 发布于:2025-04-03 17:18 新学校选址(找到一个数组排序后的中位数,如果是基数就是这个数,如果是偶数就是这个数的前一个数) 发布于:2025-04-03 16:38 绘图机器(从(0,0)到第一个点时,是先走横坐标,再走纵坐标,所以第一个点的面积应该为0) 发布于:2025-04-02 19:14 素数之积(判断是否为素数的函数:function isPrime(n) { if (n < 2) return false; for (let i = 2; i <= Math.sqrt(n); i++) { if (n % i === 0) return false; } return true; } 发布于:2025-04-02 17:43 考勤信息(滑动窗口统计七天之内的考勤状况) 发布于:2025-04-02 17:27 打印机队列(简单的数组模拟) 发布于:2025-04-02 16:29 JS AES128加解密 发布于:2025-04-03 15:28 找出重复代码】(二维动态规划:定义二维数组dp,初始值设为0,循环两个字符串,如果str1[i]=str2[j],dp[i+1][j+1]==dp[i][j]+1;使用maxLength定义当前最大的公共子串长度,如果dp[i+1][j+1]>maxLength,记录maxLength和当前结束位置i+1。循环后,根据maxLength和结束位置p,确定silce的范围 发布于:2025-04-01 19:24 【二叉树中序遍历】(用栈将二叉树的结构处理出来。然后中序遍历) 发布于:2025-04-01 19:08 【最小调整顺序次数】(模拟队列操作:当插入操作为头操作时,如果数组不为空,就不是排序状态。尾插入不影响;当移除元素时,如果当前队列是有序的 ,就不需要操作,否则就需要操作,ans++) 发布于:2025-04-01 18:29 二元组个数】(用map存储第一个数组中出现的元素及个数,然后遍历第二个数组,如果遇到map中的元素,ans+=map.get()) 发布于:2025-04-01 18:02 【文件目录大小】(递归:先读取每个文件的信息,解析每行输入的三个部分:id,size,child并将处理过后的放入files中,files:{id,size,child}。然后递归计算目标目录的大小:自定义一个递归函数 getSize,将目标目录设为root节点,向下递归子文件夹,如果有子文件夹就递归计算所有子节点的大小并累加,最后返回结果) 发布于:2025-04-01 17:49 华为OD机试真题 Python 实现【水库蓄水问题】(变体接雨水问题,用双指针遍历数组,然后将子数组内的每一个数字能接到的雨水相加(如果当前位置数字 小于左右边界的最小值,能够接水),如果有多个位置接的雨水相同,保留right-left最小的) 发布于:2025-04-01 17:23 找出两个整数数组中同时出现的整数】(用map存储第一个数组中的元素,然后再循环第二个数组,当遇到map中有的数字时,记录下这个数字。再创建新的Map,按出现次数分组存储数字// 获取当前数字及其在第一个数组中的出现次数// 将数字添加到对应次数的组中,并保持组内数字有序;// 获取所有出现次数并按升序排序// 按格式输出结果) 发布于:2025-04-01 16:47 模拟消息队列(两个数组,一个用来存消息,一个用来存接受者,接受者的中包括订阅时间取消时间和能接收到的消息,正序循环message数组,在逆序循环接受者数组,每当有发送消息的时间在订阅和取关之间时,把这个消息放到消息队列中) 发布于:2025-04-01 16:22 【投篮大赛】(简单字符串操作) 发布于:2025-04-01 16:05 【数值同化】(广度优先搜索,搜索能够到达的所有格子,然后遍历矩阵找出无法到达的地区) 发布于:2025-04-01 15:29 数字加减游戏(数学问题:先判断目标-初始是否能被b整除,如果能直接输出0.如果不能就每次判断初始值+a*x或初始值-a*x是否能整除b,如果能,就时最优解) 发布于:2025-04-01 15:10 数组二叉树(// 遍历树中的所有节点,寻找最小的叶子节点 // 判断当前节点是否为叶子节点,需满足以下条件: // 1. 节点值不为 -1(不是空节点) // 2. 节点值小于当前找到的最小叶子值 // 3. 左子节点不存在(超出数组范围或为-1) // 4. 右子节点不存在(超出数组范围或为-1) // 更新最小叶子节点的索引和值,找到叶子节点后,根据叶子节点不断向上推导出父节点,直到找到根节点。对于索引i,其父节点索引为 floor((i-1)/2)) 发布于:2025-04-01 14:56 【招聘】计算至少需要的面试官数量( // 核心算法思路: // 1. 首先对所有面试时间区间按开始时间排序 // 2. 检查相邻区间是否存在时间重叠 // 3. 对于重叠的区间,需要额外的面试官 // 4. 最后根据重叠情况和每个面试官的面试次数限制(m)计算所需面试官总数) 发布于:2025-03-31 18:44 查找一个有向网络的头节点和尾节点(读取输入数据并解析 统计每个节点的入度和出度 使用Map存储节点的入度和出度 每处理一条边,同时更新起点和终点的度数 入度为0的节点是起点 出度为0的节点是终点 终点需要降序排序 检查是否存在起点和终点 收集所有起点和终点 对终点进行排序 输出结果) 发布于:2025-03-31 17:51 [更多]
显示目录

TLS/SSL



学习嵌入式的绝佳套件,esp8266开源小电视成品,比自己去买开发板+屏幕还要便宜,省去了焊接不当搞坏的风险。 蜂鸣版+触控升级仅36元,更强的硬件、价格全网最低。

点击购买 固件广场

TLS/SSL

Stability: 3 - Stable

Node.js可以使用require('tls')来访问TLS/SSL模块:

const tls = require('tls');

tls模块使用OpenSSL来提供传输层安全性(Transport Layer Security,TLS)和安全套接层(Secure Socket Layer,SSL):加密过的流通讯。

TLS/SSL是一种公钥/私钥基础架构,每个客户端和服务端都需要一个私钥。私钥的创建方法如下:

openssl genrsa -out ryans-key.pem 2048

你还需要为所有服务器和某些客户端添加证书。证书由认证中心(Certificate Authority)签名,或者自签名。获得证书第一步是创建一个证书签名请求"Certificate Signing Request" (CSR)文件。证书的创建方法如下:

openssl req -new -sha256 -key ryans-key.pem -out ryans-csr.pem

使用CSR创建一个自签名的证书:

openssl x509 -req -in ryans-csr.pem -signkey ryans-key.pem -out ryans-cert.pem

或者你可以发送CSR给认证中心(Certificate Authority)来签名。

(TODO: 创建CA的文档,感兴趣的读者可以在Node源码test/fixtures/keys/Makefile里查看)

创建.pfx或.p12,可以这么做:

openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \
    -certfile ca-cert.pem -out agent5.pfx
  • in: 签名证书
  • inkey: 关联的私钥
  • certfile: 是将所有证书颁发机构 (CA) 证书连接到单个文件中,例如,cat ca1-cert.pem ca2-cert.pem > ca-cert.pem

协议支持

Node.js默认遵循SSLv2和SSLv3协议,不过这些协议被禁用。因为他们不太可靠,很容易受到威胁,参见CVE-2014-3566。某些情况下,旧版本客户端/服务器(比如 IE6)可能会产生问题。如果你想启用SSLv2或SSLv3 ,使用参数--enable-ssl2--enable-ssl3运行Node。Node.js的未来版本中不会再默认编译SSLv2 和SSLv3。

有一个办法可以强制node进入仅使用SSLv3或SSLv2模式,分别指定secureProtocol'SSLv3_method''SSLv2_method'

Node.js使用的默认协议方法准确名字是AutoNegotiate_method, 这个方法会尝试并协商客户端支持的从高到底协议。为了提供默认的安全级别,Node.js(v0.10.33 版本之后)通过将secureOptions设为SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2 ,明确的禁用了SSLv3和SSLv2(除非你给secureProtocol 传值--enable-ssl3,或--enable-ssl2,或SSLv3_method)。

如果你设置了secureOptions,我们不会重新这个参数。

改变这个行为的后果:

  • 如果你的应用被当做为安全服务器,SSLv3客户端不能协商建立连接,会被拒绝。这种情况下,你的服务器会触发clientError事件。错误消息会包含错误版本数字('wrong version number')。
  • 如果你的应用被当做安全客户端,和一个不支持比SSLv3更高安全性的方法的服务器通讯,你的连接不会协商成功。这种情况下,你的客户端会触发 clientError事件。错误消息会包含错误版本数字('wrong version number')。

Client-initiated renegotiation attack mitigation

TLS协议让客户端协商TLS会话的某些方法内容。但是,会话协商需要服务器端响应的资源,这回让它成为阻断服务攻击(denial-of-service attacks)的潜在媒介。

为了降低这种情况的发生,重新协商被限制为每10分钟3次。当超出这个界限时,在tls.TLSSocket实例上会触发错误。这个限制可设置:

  • tls.CLIENT_RENEG_LIMIT: 重新协商limit,默认是3。

  • tls.CLIENT_RENEG_WINDOW: 重新协商窗口的时间,单位秒,默认是10分钟。

除非你明确知道自己在干什么,否则不要改变默认值。

要测试你的服务器的话,使用openssl s_client -connect address:port连接服务器,并敲R<CR>(字母 R 键加回车)几次。

NPN 和 SNI

NPN(Next Protocol Negotiation 下次协议协商)和SNI (Server Name Indication 域名指示)都是TLS握手扩展:

  • NPN - 同一个TLS服务器使用多种协议 (HTTP, SPDY)
  • SNI - 同一个TLS服务器使用多个主机名(不同的 SSL 证书)。certificates.

完全正向保密

"Forward Secrecy"或"Perfect Forward Secrecy-完全正向保密"协议描述了秘钥协商(比如秘钥交换)方法的特点。实际上这意味着及时你的服务器的秘钥有危险,通讯仅有可能被一类人窃听,他们必须设法获的每次会话都会生成的秘钥对。

完全正向保密是通过每次握手时为秘钥协商随机生成密钥对来完成(和所有会话一个key相反)。实现这个技术(提供完全正向保密-Perfect Forward Secrecy)的方法被称为"ephemeral"。

通常目前有2个方法用于完成完全正向保密(Perfect Forward Secrecy):

  • DHE - 一个迪菲-赫尔曼密钥交换密钥协议(Diffie Hellman key-agreement protocol)短暂(ephemeral)版本。
  • ECDHE - 一个椭圆曲线密钥交换密钥协议( Elliptic Curve Diffie Hellman key-agreement protocol)短暂(ephemeral)版本。

短暂(ephemeral)方法有性能缺点,因为生成 key 非常耗费资源。

tls.getCiphers()

返回支持的SSL密码名数组。

例子:

var ciphers = tls.getCiphers();
console.log(ciphers); // ['AES128-SHA', 'AES256-SHA', ...]

tls.createServer(options[, secureConnectionListener])

创建一个新的tls.Server。参数connectionListener会自动设置为secureConnection事件的监听器。参数options对象有以下可能性:

  • pfx: 包含私钥,证书和服务器的CA证书(PFX或PKCS12 格式)字符串或缓存Buffer。(keycertca互斥)。

  • key: 包含服务器私钥(PEM格式)字符串或缓存Buffer。(可以是keys的数组)(必传)。

  • passphrase: 私钥或pfx的密码字符串

  • cert: 包含服务器证书key(PEM格式)字符串或缓存Buffer。(可以是certs的数组)(必传)。

  • ca: 信任的证书(PEM格式)的字符串/缓存数组。如果忽略这个参数,将会使用"root" CAs ,比如VeriSign。用来授权连接。

  • crl : 不是PEM编码CRLs (证书撤销列表 Certificate Revocation List)的字符串就是字符串列表.

  • ciphers: 要使用或排除的密码(cipher)字符串

    为了减轻BEAST attacks ,推荐使用这个参数和之后会提到的honorCipherOrder参数来优化non-CBC密码(cipher)

    默认:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL。格式上更多细节参见OpenSSL cipher list format documentation

    ECDHE-RSA-AES128-SHA256, DHE-RSA-AES128-SHA256AES128-GCM-SHA256都是TLS v1.2密码(cipher),当node.js连接OpenSSL 1.0.1或更早版本(比如)时使用。注意,honorCipherOrder设置为enabled后,现在仍然可以和TLS v1.2客户端协商弱密码(cipher),

    RC4可作为客户端和老版本TLS协议通讯的备用方法。RC4这些年受到怀疑,任何对信任敏感的对象都会考虑其威胁性。国家级别(state-level)的参与者拥有中断它的能力。

    注意: 早些版本的修订建议,AES256-SHA作为可以接受的密码(cipher).Unfortunately,AES256-SHA是一个CBC密码(cipher),容易受到BEAST attacks 攻击,不要使用它。

  • ecdhCurve: 包含用来ECDH秘钥交换弧形(curve)名字符串,或者false禁用ECDH。

    默认prime256v1。更多细节参考RFC 4492

  • dhparam: DH参数文件,用于DHE秘钥协商。使用openssl dhparam命令来创建。如果加载文件失败,会悄悄的抛弃它。

  • handshakeTimeout: 如果SSL/TLS握手事件超过这个参数,会放弃里连接。默认是120秒.

    握手超时后,tls.Server对象会触发'clientError'事件。

  • honorCipherOrder: 当选择一个密码(cipher)时,使用服务器配置,而不是客户端的。

    虽然这个参数默认不可用,还是推荐你用这个参数,和ciphers参数连接使用,减轻BEAST攻击。

    注意,如果使用了SSLv2,服务器会发送自己的配置列表给客户端,客户端会挑选密码(cipher)。默认不支持SSLv2,除非node.js配置了./configure --with-sslv2

  • requestCert: 如果设为true,服务器会要求连接的客户端发送证书,并尝试验证证书。默认:false

  • rejectUnauthorized: 如果为true,服务器将会拒绝任何不被CAs列表授权的连接。仅requestCert参数为true时这个参数才有效。默认:false

  • checkServerIdentity(servername, cert): 提供一个重写的方法来检查证书对应的主机名。如果验证失败,返回error。如果验证通过,返回undefined

  • NPNProtocols: NPN协议的Buffer数组(协议需按优先级排序)。

  • SNICallback(servername, cb): 如果客户端支持SNI TLS扩展会调用这个函数。会传入2个参数:servernamecbSNICallback必须调用 cb(null, ctx),其中ctx是SecureContext实例。(你可以用tls.createSecureContext(...)来获取相应的SecureContext上下文)。如果 SNICallback没有提供,将会使用高级的API(参见下文).

  • sessionTimeout: 整数,设定了服务器创建TLS会话标示符(TLS session identifiers)和TLS会话票据(TLS session tickets)后的超时时间(单位:秒)。更多细节参见:SSL_CTX_set_timeout

  • ticketKeys: 一个48字节的Buffer实例,由16字节的前缀,16字节的hmac key,16字节的AES key组成。可用用它来接受tls服务器实例上的tls会话票据(tls session tickets)。

    注意: 自动在集群模块( cluster module)工作进程间共享。

  • sessionIdContext: 会话恢复(session resumption)的标示符字符串。如果requestCerttrue。默认值为命令行生成的MD5哈希值。否则不提供默认值。

  • secureProtocol: SSL使用的方法,例如,SSLv3_method强制SSL版本为3。可能的值定义于你所安装的OpenSSL中的常量SSL_METHODS

  • secureOptions: 设置服务器配置。例如设置SSL_OP_NO_SSLv3可用禁用SSLv3协议。所有可用的参数见SSL_CTX_set_options

响应服务器的简单例子:

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

var options = {
  key: fs.readFileSync('server-key.pem'),
  cert: fs.readFileSync('server-cert.pem'),

  // This is necessary only if using the client certificate authentication.
  requestCert: true,

  // This is necessary only if the client uses the self-signed certificate.
  ca: [ fs.readFileSync('client-cert.pem') ]
};

var server = tls.createServer(options, function(socket) {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write("welcome!\n");
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, function() {
  console.log('server bound');
});

或者:

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

var options = {
  pfx: fs.readFileSync('server.pfx'),

  // This is necessary only if using the client certificate authentication.
  requestCert: true,

};

var server = tls.createServer(options, function(socket) {
  console.log('server connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  socket.write("welcome!\n");
  socket.setEncoding('utf8');
  socket.pipe(socket);
});
server.listen(8000, function() {
  console.log('server bound');
});

你可以通过openssl s_client连接服务器来测试:

openssl s_client -connect 127.0.0.1:8000

tls.connect(options[, callback])

tls.connect(port[, host][, options][, callback])

创建一个新的客户端连接到指定的端口和主机(port and host)(老版本API),或者options.portoptions.host(如果忽略host,默认为 localhost)。options是一个包含以下值得对象:

  • host: 客户端需要连接到的主机。

  • port: 客户端需要连接到的端口。

  • socket: 在指定的socket(而非新建)上建立安全连接。如果这个参数有值,将忽略hostport参数。

  • path: 创建 到参数path的unix socket连接。如果这个参数有值,将忽略hostport参数。

  • pfx: 包含私钥,证书和客户端(PFX或PKCS12格式)的CA证书的字符串或Buffer缓存。

  • key: 包含客户端(PEM格式)的 私钥的字符串或Buffer缓存。可以是keys数组。

  • passphrase: 私钥或pfx的密码字符串。

  • cert: 包含客户端证书key(PEM格式)字符串或缓存Buffer。(可以是certs的数组)。

  • ca: 信任的证书(PEM格式)的字符串/缓存数组。如果忽略这个参数,将会使用"root" CAs ,比如VeriSign。用来授权连接。

  • rejectUnauthorized: 如果为true,服务器证书根据CAs列表授权列表验证。如果验证失败,触发'error'事件;err.code包含OpenSSL错误代码。默认:true

  • NPNProtocols: NPN协议的字符串或Buffer数组。Buffer必须有以下格式0x05hello0x05world,第一个字节是下一个协议名字的长度。(传的数组通常非常简单,比如:['hello', 'world'])。

  • servername: SNI(域名指示 Server Name Indication) TLS扩展的服务器名。

  • secureProtocol: SSL使用的方法,例如,SSLv3_method强制SSL版本为3。可能的值定义于你所安装的OpenSSL中的常量SSL_METHODS

  • session: 一个Buffer实例,包含TLS会话.

将参数callback添加到'secureConnect'事件上,其效果如同监听器。

tls.connect()返回一个tls.TLSSocket对象。

这是一个简单的客户端应答服务器例子:

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

var options = {
  // These are necessary only if using the client certificate authentication
  key: fs.readFileSync('client-key.pem'),
  cert: fs.readFileSync('client-cert.pem'),

  // This is necessary only if the server uses the self-signed certificate
  ca: [ fs.readFileSync('server-cert.pem') ]
};

var socket = tls.connect(8000, options, function() {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', function(data) {
  console.log(data);
});
socket.on('end', function() {
  server.close();
});

或者:

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

var options = {
  pfx: fs.readFileSync('client.pfx')
};

var socket = tls.connect(8000, options, function() {
  console.log('client connected',
              socket.authorized ? 'authorized' : 'unauthorized');
  process.stdin.pipe(socket);
  process.stdin.resume();
});
socket.setEncoding('utf8');
socket.on('data', function(data) {
  console.log(data);
});
socket.on('end', function() {
  server.close();
});

类: tls.TLSSocket

net.Socket实例的封装,取代内部socket读写程序,执行透明的输入/输出数据的加密/解密。

new tls.TLSSocket(socket, options)

从现有的TCP socket里构造一个新的TLSSocket对象。

socket一个net.Socket的实例

options一个包含以下属性的对象:

  • secureContext: 来自tls.createSecureContext( ... )的可选TLS上下文对象。

  • isServer: 如果为true, TLS socket将会在服务器模式(server-mode)初始化。

  • server: 一个可选的net.Server实例

  • requestCert: 可选的,参见tls.createSecurePair

  • rejectUnauthorized: 可选的,参见tls.createSecurePair

  • NPNProtocols: 可选的,参见tls.createServer

  • SNICallback: 可选的,参见tls.createServer

  • session: 可选的,一个Buffer实例,包含TLS会话

  • requestOCSP: 可选的,如果为true- OCSP状态请求扩展将会被添加到客户端hello,并且OCSPResponse事件将会在socket上建立安全通讯前触发。

tls.createSecureContext(details)

创建一个凭证(credentials)对象,包含字典有以下的key:

  • pfx : 包含PFX或PKCS12加密的私钥,证书和服务器的CA证书(PFX或PKCS12格式)字符串或缓存Buffer。(keycertca互斥)。
  • key : 包含PEM加密过的私钥的字符串。
  • passphrase : 私钥或pfx的密码字符串。
  • cert : 包含PEM加密过的证书的字符串。
  • ca : 信任的PEM加密过的可信任的证书(PEM格式)字符串/缓存数组。
  • crl :PEM加密过的CRLs(证书撤销列表)
  • ciphers: 要使用或排除的密码(cipher)字符串。更多格式上的细节参见http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
  • honorCipherOrder : 当选择一个密码(cipher) 时, 使用服务器配置,而不是客户端的。 更多细节参见tls模块文档。

如果没给 'ca' 细节,node.js 将会使用默认的公开信任的 CAs 列表(参见http://mxr.mozilla.org/mozilla/source/security/nss/lib/ckfw/builtins/certdata.txt)。

tls.createSecurePair([context][, isServer][, requestCert][, rejectUnauthorized])

创建一个新的安全对(secure pair)对象,包含2个流,其中一个读/写加密过的数据,另外一个读/写明文数据。通常加密端数据来自是从输入的加密数据流,另一端被当做初始加密流。

  • credentials: 来自tls.createSecureContext( ... )的安全上下文对象。

  • isServer: 是否以服务器/客户端模式打开这个tls连接。

  • requestCert: 是否服务器需要连接的客户端发送证书。仅适用于服务端连接。

  • rejectUnauthorized:非法证书时,是否服务器需要自动拒绝客户端。启用requestCert后,才适用于服务器。

tls.createSecurePair()返回一个安全对(SecurePair)对象,包含明文cleartext和密文encrypted流 。

注意: cleartexttls.TLSSocket拥有相同的 API。

类: SecurePair

通过tls.createSecurePair返回。

事件: 'secure'

一旦安全对(SecurePair)成功建立一个安全连接,安全对(SecurePair)将会触发这个事件。

和检查服务器'secureConnection'事件一样,pair.cleartext.authorized必须检查确认是否适用的证书是授权过的。

类: tls.Server

这是net.Server的子类,拥有相同的方法。这个类接受适用TLS或SSL的加密连接,而不是接受原始TCP连接。

事件: 'secureConnection'

function (tlsSocket) {}

新的连接握手成功后回触发这个事件。参数是tls.TLSSocket实例。它拥有常用的流方法和事件。

socket.authorized是否客户端被证书(服务器提供)授权。如果socket.authorized为false,socket.authorizationError是如何授权失败。值得一提的是,依赖于TLS服务器的设置,你的未授权连接可能也会被接受。socket.authorizationError如何授权失败。值得一提的是,依赖于TLS服务器的设置,你的未授权连接可能也会被接受。socket.npnProtocol包含选择的NPN协议的字符串。socket.servername包含SNI请求的服务器名的字符串。

事件: 'clientError'

function (exception, tlsSocket) { }

在安全连接建立前,客户端连接触发'error'事件会转发到这里来。

tlsSockettls.TLSSocket,错误是从这里触发的。

事件: 'newSession'

function (sessionId, sessionData, callback) { }

创建TLS会话的时候会触发。可能用来在外部存储器里存储会话。callback必须最后调用,否则没法从安全连接发送/接收数据。

注意: 添加这个事件监听器仅会在连接连接时有效果。

事件: 'resumeSession'

function (sessionId, callback) { }

当客户端想恢复之前的TLS会话时会触发。事件监听器可能会使用sessionId到外部存储器里查找,一旦结束会触发callback(null, sessionData)。如果会话不能恢复(比如不存在这个会话),可能会调用callback(null, null)。调用callback(err)将会终止连接,并销毁socket。

注意: 添加这个事件监听器仅会在连接连接时有效果。

事件: 'OCSPRequest'

function (certificate, issuer, callback) { }

当客户端发送证书状态请求时会触发。你可以解析服务器当前的证书,来获取OCSP网址和证书id,获取OCSP响应调用callback(null, resp),其中respBuffer实例。证书(certificate)和发行者(issuer)都是初级表达式缓存(BufferDER-representations of the primary)和证书的发行者。它可以用来获取OCSP证书和OCSP终点网址。

可以调用callback(null, null),表示没有OCSP响应。

调用callback(err)可能会导致调用socket.destroy(err)

典型流程:

  1. 客户端连接服务器,并发送OCSPRequest(通过 ClientHello 里的状态信息扩展)。
  2. 服务器收到请求,调用OCSPRequest事件监听器。
  3. 服务器从certificateissuer获取OCSP网址,并执行OCSP request到CA
  4. 服务器CA收到OCSPResponse, 并通过callback参数送回到客户端
  5. 客户端验证响应,并销毁socket或执行握手

注意: 如果证书是自签名的,或者如果发行者不再根证书列表里(你可以通过参数提供一个发行者)。issuer就可能为null。

注意:添加这个事件监听器仅会在连接连接时有效果。

注意:你可以能想要使用npm模块(比如asn1.js)来解析证书。

server.listen(port[, host][, callback])

在指定的端口和主机上开始接收连接。如果host参数没传,服务接受通过IPv4地址(INADDR_ANY)的直连。

这是异步函数。当服务器已经绑定后回调用最后一个参数callback

更多信息参见net.Server

server.close()

停止服务器,不再接收新连接。这是异步函数,当服务器触发'close'事件后回最终关闭。

server.address()

返回绑定的地址,地址家族名和服务器端口。更多信息参见net.Server.address()

server.addContext(hostname, context)

如果客户端请求SNI主机名和传入的hostname相匹配,将会用到安全上下文(secure context)。context可以包含keycertca和/或tls.createSecureContext``options参数的其他任何属性。

server.maxConnections

设置这个属性可以在服务器的连接数达到最大值时拒绝连接。

server.connections

当前服务器连接数。

类: CryptoStream

稳定性: 0 - 抛弃. 使用 tls.TLSSocket 替代.

这是一个加密的流

cryptoStream.bytesWritten

底层socket写字节访问器(bytesWritten accessor)的代理,将会返回写到socket的全部字节数。包括 TLS 的开销。

类: tls.TLSSocket

net.Socket实例的封装,透明的加密写数据和所有必须的TLS协商。

这个接口实现了一个双工流接口。它包含所有常用的流方法和事件。

事件: 'secureConnect'

新的连接成功握手后回触发这个事件。无论服务器证书是否授权,都会调用监听器。用于用户测试tlsSocket.authorized看看如果服务器证书已经被指定的CAs签名。如果tlsSocket.authorized === false ,可以在tlsSocket.authorizationError里找到错误。如果使用了NPN,你可以检tlsSocket.npnProtocol获取协商协议(negotiated protocol)。

事件: 'OCSPResponse'

function (response) { }

如果启用requestOCSP参赛会触发这个事件。response是缓存对象,包含服务器的OCSP响应。

一般来说,response是服务器CA签名的对象,它包含服务器撤销证书状态的信息。

tlsSocket.encrypted

静态boolean变量,一直是true。可以用来区别TLS socket和常规对象。

tlsSocket.authorized

boolean变量,如果对等实体证书(peer's certificate)被指定的某个CAs签名,返回true,否则false

tlsSocket.authorizationError

对等实体证书(peer's certificate)没有验证通过的原因。当tlsSocket.authorized === false时,这个属性才可用。

tlsSocket.getPeerCertificate([ detailed ])

返回一个代表对等实体证书( peer's certificate)的对象。这个返回对象有一些属性和证书内容相对应。如果参数detailedtrue,将会返回包含发行者issuer完整链。如果false,仅有顶级证书没有发行者issuer属性。

例子:

{ subject:
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  issuerInfo:
   { C: 'UK',
     ST: 'Acknack Ltd',
     L: 'Rhys Jones',
     O: 'node.js',
     OU: 'Test TLS Certificate',
     CN: 'localhost' },
  issuer:
   { ... another certificate ... },
  raw: < RAW DER buffer >,
  valid_from: 'Nov 11 09:52:22 2009 GMT',
  valid_to: 'Nov  6 09:52:22 2029 GMT',
  fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF',
  serialNumber: 'B9B0D332A1AA5635' }

如果peer没有提供证书,返回null或空对象。

tlsSocket.getCipher()

返回一个对象,它代表了密码名和当前连接的SSL/TLS协议的版本。

例子:{ name: 'AES256-SHA', version: 'TLSv1/SSLv3' }

更多信息参见http://www.openssl.org/docs/ssl/ssl.html#DEALING\_WITH\_CIPHERS里的SSL\_CIPHER\_get\_name()和SSL\_CIPHER\_get\_version() 。

tlsSocket.renegotiate(options, callback)

初始化 TLS 重新协商进程。参数options可能包含以下内容:rejectUnauthorizedrequestCert(细节参见tls.createServer)。一旦重新协商成(renegotiation)功完成,将会执行callback(err),其中errnull

注意:当安全连接建立后,可以用这来请求对等实体证书(peer's certificate)。

注意:作为服务器运行时,handshakeTimeout超时后,socket将会被销毁。

tlsSocket.setMaxSendFragment(size)

设置最大的TLS碎片大小(默认最大值为:16384,最小值为:512)。成功的话,返回true,否则返回false

小的碎片包会减少客户端的缓存延迟:大的碎片直到接收完毕后才能被TLS层完全缓存,并且验证过完整性;大的碎片可能会有多次往返,并且可能会因为丢包或重新排序导致延迟。而小的碎片会增加额外的TLS帧字节和CPU负载,这会减少CPU的吞吐量。

tlsSocket.getSession()

返回ASN.1编码的TLS会话,如果没有协商,会返回。连接到服务器时,可以用来加速握手的建立。

tlsSocket.getTLSTicket()

注意:仅和客户端TLS socket打交道。仅在调试时有用,会话重用是,提供session参数给tls.connect

返回TLS会话票据(ticket),或如果没有协商(negotiated),返回undefined

tlsSocket.address()

返回绑定的地址,地址家族名和服务器端口。更多信息参见net.Server.address()。返回三个属性, 比如:{ port: 12346, family: 'IPv4', address: '127.0.0.1' }

tlsSocket.remoteAddress

表示远程IP地址(字符串表示),例如:'74.125.127.100''2001:4860:a005::68'.

tlsSocket.remoteFamily

表示远程 IP 家族,'IPv4''IPv6'

tlsSocket.remotePort

远程端口(数字表示),例如,443

tlsSocket.localAddress

本地IP地址(字符串表示)。

tlsSocket.localPort

本地端口号(数字表示)。

由JSRUN为你提供的JS在线运行、在线编译工具
        JSRUN提供的JS 在线运行,JS 在线运行工具,基于linux操作系统环境提供线上编译和线上运行,具有运行快速,运行结果与常用开发、生产环境保持一致的特点。
yout