如何用nodejs 解密 通过golang加密的文件

Python015

如何用nodejs 解密 通过golang加密的文件,第1张

以下代码采用AES192,128的类似

var crypto = require('crypto')var key = crypto.randomBytes(192/8) // 替换成自己需要的keyvar iv = crypto.randomBytes(128/8) // 替换成自己需要的ivvar algorithm = 'aes192'function encrypt(text){var cipher = crypto.createCipheriv(algorithm, key, iv)

cipher.update(text) return cipher.final('hex')

}function decrypt(encrypted){var decipher = crypto.createDecipheriv(algorithm, key, iv)

decipher.update(encrypted, 'hex') return decipher.final('utf8')

}var content = 'hello'var crypted = encrypt('hello')console.log( crypted ) // 输出:1b87be446405ff910cd280ae6aa0423fvar decrypted = decrypt( crypted )console.log( decrypted ) // 输出:he

微服务架构已成为目前互联网架构的趋势,关于微服务的讨论,几乎占据了各种技术大会的绝大多数版面。国内使用最多的服务治理框架非阿里开源的 dubbo 莫属,千米网也选择了 dubbo 作为微服务治理框架。另一方面,和大多数互联网公司一样,千米的开发语言是多样的,大多数后端业务由 java 支撑,而每个业务线有各自开发语言的选择权,便出现了 nodejs,python,go 多语言调用的问题。

跨语言调用是一个很大的话题,也是一个很有挑战的技术活,目前业界经常被提及的解决方案有如下几种,不妨拿出来老生常谈一番:

当我们再聊跨语言调用时我们在聊什么?纵观上述几个较为通用,成熟的解决方案,可以得出结论:解决跨语言调用的思路无非是两种:

如果一个新型的团队面临技术选型,我认为上述的方案都可以纳入参考,可考虑到遗留系统的兼容性问题

旧系统的迁移成本

这也关键的选型因素。我们做出的第一个尝试,便是在 RPC 协议上下功夫。

通用协议的跨语言支持

springmvc的美好时代

springmvc

springmvc

在没有实现真正的跨语言调用之前,想要实现“跨语言”大多数方案是使用 http 协议做一层转换,最常见的手段莫过于借助 springmvc 提供的 controller/restController,间接调用 dubbo provider。这种方案的优势和劣势显而易见

通用协议的支持

事实上,大多数服务治理框架都支持多种协议,dubbo 框架除默认的 dubbo 协议之外,还有当当网扩展的 rest协议和千米网扩展的 json-rpc 协议可供选择。这两者都是通用的跨语言协议。

rest 协议为满足 JAX-RS 2.0 标准规范,在开发过程中引入了 @Path,@POST,@GET 等注解,习惯于编写传统 rpc 接口的人可能不太习惯 rest 风格的 rpc 接口。一方面这样会影响开发体验,另一方面,独树一帜的接口风格使得它与其他协议不太兼容,旧接口的共生和迁移都无法实现。如果没有遗留系统,rest 协议无疑是跨语言方案最简易的实现,绝大多数语言支持 rest 协议。

和 rest 协议类似,json-rpc 的实现也是文本序列化&http 协议。dubbox 在 restful 接口上已经做出了尝试,但是 rest 架构和 dubbo 原有的 rpc 架构是有区别的,rest 架构需要对资源(Resources)进行定义, 需要用到 http 协议的基本操作 GET、POST、PUT、DELETE。在我们看来,restful 更合适互联网系统之间的调用,而 rpc 更适合一个系统内的调用。使用 json-rpc 协议使得旧接口得以兼顾,开发习惯仍旧保留,同时获得了跨语言的能力。

千米网在早期实践中采用了 json-rpc 作为 dubbo 的跨语言协议实现,并开源了基于 json-rpc 协议下的 python 客户端 dubbo-client-py 和 node 客户端 dubbo-node-client,使用 python 和 nodejs 的小伙伴可以借助于它们直接调用 dubbo-provider-java 提供的 rpc 服务。系统中大多数 java 服务之间的互相调用还是以 dubbo 协议为主,考虑到新旧协议的适配,在不影响原有服务的基础上,我们配置了双协议。

dubbo 协议主要支持 java 间的相互调用,适配老接口;json-rpc 协议主要支持异构语言的调用。

定制协议的跨语言支持

微服务框架所谓的协议(protocol)可以简单理解为:报文格式和序列化方案。服务治理框架一般都提供了众多的协议配置项供使用者选择,除去上述两种通用协议,还存在一些定制化的协议,如 dubbo 框架的默认协议:dubbo 协议以及 motan 框架提供的跨语言协议:motan2。

motan2协议的跨语言支持

                                                                                                            motan2

motan2

motan2 协议被设计用来满足跨语言的需求主要体现在两个细节中—MetaData 和 motan-go。在最初的 motan 协议中,协议报文仅由 Header+Body 组成,这样导致 path,param,group 等存储在 Body 中的数据需要反序列得到,这对异构语言来说是很不友好的,所以在 motan2 中修改了协议的组成;weibo 开源了 motan-go ,motan-php ,motan-openresty ,并借助于 motan-go 充当了 agent 这一翻译官的角色,使用 simple 序列化方案来序列化协议报文的 Body 部分(simple 序列化是一种较弱的序列化方案)。

                                                                                                        agent

agent

仔细揣摩下可以发现这么做和双协议的配置区别并不是大,只不过这里的 agent 是隐式存在的,与主服务共生。明显的区别在于 agent 方案中异构语言并不直接交互。

dubbo协议的跨语言支持

dubbo 协议设计之初只考虑到了常规的 rpc 调用场景,它并不是为跨语言而设计,但跨语言支持从来不是只有支持、不支持两种选择,而是要按难易程度来划分。是的,dubbo 协议的跨语言调用可能并不好做,但并非无法实现。千米网便实现了这一点,nodejs 构建的前端业务是异构语言的主战场,最终实现了 dubbo2.js,打通了 nodejs 和原生 dubbo 协议。作为本文第二部分的核心内容,重点介绍下我们使用 dubbo2.js 干了什么事。

Dubbo协议报文格式

                                                                                                        dubbo协议

dubbo协议

dubbo协议报文消息头详解:

magic:类似java字节码文件里的魔数,用来判断是不是 dubbo 协议的数据包。魔数是常量 0xdabb

flag:标志位, 一共8个地址位。低四位用来表示消息体数据用的序列化工具的类型(默认 hessian),高四位中,第一位为 1 表示是 request 请求,第二位为 1 表示双向传输(即有返回 response),第三位为 1 表示是心跳 ping 事件。

status:状态位, 设置请求响应状态,dubbo 定义了一些响应的类型。具体类型见com.alibaba.dubbo.remoting.exchange.Response

invoke id:消息 id, long 类型。每一个请求的唯一识别 id(由于采用异步通讯的方式,用来把请求 request 和返回的 response 对应上)

body length:消息体 body 长度, int 类型,即记录 Body Content 有多少个字节

body content:请求参数,响应参数的抽象序列化之后存储于此。

协议报文最终都会变成字节,使用 tcp 传输,任何语言只要支持网络模块,有类似 Socket 之类的封装,那么通信就不成问题。那,跨语言难在哪儿?以其他语言调用 java 来说,主要有两个难点:

ps:dubbo 协议通讯demo( https://github.com/lexburner/Dubbojs-Learning )

一、使用Express创建项目[这两步都在dos 模式下执行]

1,安装全局的Express!(已安装请忽略)

npm install -g express

2,创建项目

创建项目(创建文件夹名称ExpressApp)

express ExpressApp

小插曲:如果你习惯了Linux下的环境,你可以在自己电脑上安装cmder(不知道是什么东西,请自行百度),这个命令行工具排版漂亮,不像微软的dos 那么枯燥!我用的是Mini版本,如果你想体验linux下的全部功能,可以下载full版本。

3,下载第三方包

(1)cmd命令行切换到项目目录

cd d:\nodejs\ExpressApp

(2)根据需要编辑package.json,运行如下指令安装第三方包

npm install

在项目目录下node_modules可见安装好的第三方包

ExpressApp

|– node_modules

(3)运行项目

npm start

输出如下:

[email protected] start d:\Nodejs_Workspace\ExpressApp

node ./bin/www

注:npm start指令会自动执行node ./bin/www

在浏览器中输入http://localhost:3000,可访问Express欢迎页面

二、使用VSCode开发Nodejs

1、VSCode打开Nodejs

code d:\nodejs\ExpressAppcode.

注:在当前项目下创建ExpressApp.bat,输入“code .”即可,下次直接此文件直接使用VSCode打开Nodejs项目

2、添加智能提示

VSCode打开Nodejs项目,默认是没有智能提示。

(1)使用TypeScript Definition Manager(TSD)在项目中下载所需的tsd文件,VSCode中打开时有智能

全局安装tsd(如已安装忽略)

npm install -g tsd

下载所需的组件提示(以下载node、express、requirejs提示为例)

tsd query node --action installtsd query express --action installtsd install require

注:

①多个提示组件在query参数后可以空格分隔简写为tsd query node express –action install

②组件会项目目录下添加typings文件夹

|– typings

|– node

|– express

|– require

(2)添加js文件引用的智能提示

假如在文件引用另外一个文件common.js时,文件头添加如下

{ // See https://go.microsoft.com/fwlink/?LinkId=759670 // for the documentation about the jsconfig.json format "compilerOptions": {"target": "es6","module": "commonjs","allowSyntheticDefaultImports": true }, "exclude": ["node_modules","bower_components","jspm_packages","tmp","temp" ]}

(小提示,如果你引入了rquire,那么你的编辑器右下方会显示一个“灯泡”的提示,你只要点灯泡就不用自己苦逼的写这个配置文件了)

此配置表示代码服从ES5标准并使用commonjs规范,发VScode下有此配置之后,可以实现在文件中对require引用js文件的智能提示。(我测试时无此配置也会有智能提示,不清楚什么原因)