• 使用 JavaScriptService 在.NET Core 里实现DES加密算法


    文章《ASP.NET Core love JavaScript》和《跨平台的 NodeJS 组件解决 .NetCore 不支持 System.Drawing图形功能的若干问题》为我们扩展.NET Core的API提供了一套解决方案,上周在看.NET的加解密算法发现目前为止没有包括DES算法,github上在才刚刚加入,具体可以看 https://group.cnblogs.com/topic/75273.html

    Node.js的Crypto库就提供各种加密算法,可以非常方便地让我们使用密码技术,解决应用开发中的问题。Crypto库是随Nodejs内核一起打包发布的,主要提供了加密、解密、签名、验证等功能。Crypto利用OpenSSL库来实现它的加密技术,它提供OpenSSL中的一系列哈希方法,包括hmac、cipher、decipher、签名和验证等方法的封装。Crypto官方文档:http://nodejs.org/api/crypto.html, 博客文章http://blog.fens.me/nodejs-crypto/ 写的非常详细。本文介绍如何使用Crypto的DES算法就可以帮助我们实现立即可用的DES算法。

    1、我们参照官方文档 https://github.com/aspnet/JavaScriptServices/tree/dev/src/Microsoft.AspNetCore.NodeServices#microsoftaspnetcorenodeservices,我们创建一个.NET Core Console应用程序 DotNETNodeApp,添加Microsoft.AspNetCore.NodeServices 包引用:

    Install-Package Microsoft.AspNetCore.NodeServices –Pre

    2、配置环境,.NET Core默认都是采用的依赖注入模式,我们在这个JavaScriptService中间件也有需求使用到依赖注入,具体参考dudu的文章:在.NET Core控制台程序中使用依赖注入


    IServiceCollection services = new ServiceCollection();
    //注入
    services.AddNodeServices(options =>
    {
        options.ProjectPath = @"C:UsersgeffzDocumentsvisual studio 2015ProjectsDotNETNodeAppsrcDotNETNodeApp";
        options.WatchFileExtensions = new[] { ".js", ".sass" };
        // ... etc. - see other properties below
    });

    //构建容器
    IServiceProvider serviceProvider = services.BuildServiceProvider();
    INodeServices nodeServices = serviceProvider.GetRequiredService<INodeServices>();

    3、我们在项目创建一个Node文件夹,然后添加一个cryptUtil.js, 文件内容如下:

    var crypto = require('crypto');

    module.exports = {
        encrypt: function (callback,plaintext, key,iv) {
            var ecb =  'des-ecb';
            var enkey = new Buffer(key);
            var eniv = new Buffer(iv ? iv : 0);
            var cipher = crypto.createCipheriv(ecb, enkey, eniv);
            cipher.setAutoPadding(true)  //default true
            var ciph = cipher.update(plaintext, 'utf8', 'base64');
            ciph += cipher.final('base64');
            callback(null /* error */, ciph);
        },

        decrypt: function (callback, encrypt_text,key, iv) {
          var ecb =  'des-ecb';
          var dekey = new Buffer(key);
            var deiv = new Buffer(iv ? iv : 0);
            var decipher = crypto.createDecipheriv(ecb, dekey, deiv);
            decipher.setAutoPadding(true);
            var txt = decipher.update(encrypt_text, 'base64', 'utf8');
            txt += decipher.final('utf8');
            callback(null, txt);
        }
    };

    这里有有个JS函数,它将在.NET 程序中被调用,通过传入一个 Node风格的回调函数和三个参数来计算结果。在NodeJS中,一个 JS 文件即代表一个模块,module.exports的意思是把当前函数作为一个对象提供出去以供调用,我们这里有两个函数分别代表加密/解密。

    4、创建一个Des 类封装NodeJs的函数调用:

    using Microsoft.AspNetCore.NodeServices;
    using System.Threading.Tasks;

    namespace DotNETNodeApp
    {
        public class Des
        {
            private INodeServices nodeServices;

            public Des(INodeServices nodeServices)
            {
                this.nodeServices = nodeServices;
            }

            public async Task<string> EncryptDES(string data, string key, int iv)
            {
                var result = await nodeServices.InvokeExportAsync<string>("./Node/cryptUtil", "encrypt", data, key, iv);
                return result;
            }

            public async Task<string> DecryptDES(string data, string key, int vi)
            {
                var result = await nodeServices.InvokeExportAsync<string>("./Node/cryptUtil", "decrypt", data,key , vi);
                return result;
            }
        }
    }

    我们再看一下InvokeExportAsync<T>(``),他是一个异步的方法,通过传入一个node.js脚本文件(模块),三个形参来得到一个结果。

    方法签名:InvokeExportAsync<T>(string moduleName, string exportName, params object[] args)


    5、我们在控制台里测试下我们的封装效果

                Des desUtil = new Des(nodeServices);
                string data = "geffzhang";
                string key = "12345678";

                string temp = desUtil.EncryptDES(data, key, 0).Result;
                Console.WriteLine(temp);
                string end = desUtil.DecryptDES(temp,key,0).Result;
                Console.WriteLine(end);
                Console.Read();

    运行一下就可以看到效果了:

    image

    6、这样使用的性能如何呢,我们用性能测试组件BenchmarkDotNet看下性能数据,使用方法参考 .NET Core性能测试组件BenchmarkDotNet 支持.NET Framework Mono:我们创建一个类DesBenchmark,在方法中加入Benchmark 特性

    using BenchmarkDotNet.Attributes;
    using Microsoft.AspNetCore.NodeServices;
    using System;
    using Microsoft.Extensions.DependencyInjection;
    using BenchmarkDotNet.Running;

    namespace DotNETNodeApp
    {
        public class DesBenchmark
        {
            private IServiceCollection services;
            private IServiceProvider serviceProvider;
            private INodeServices nodeServices;

            public DesBenchmark()
            {
                IServiceCollection services = new ServiceCollection();
                //注入
                services.AddNodeServices(options =>
                {
                    options.ProjectPath = @"C:UsersgeffzDocumentsvisual studio 2015ProjectsDotNETNodeAppsrcDotNETNodeApp";
                    options.WatchFileExtensions = new[] { ".js", ".sass" };
                    // ... etc. - see other properties below
                });

                //构建容器
                serviceProvider = services.BuildServiceProvider();
                nodeServices = serviceProvider.GetRequiredService<INodeServices>();
            }

            private string data = "geffzhang";
            private string encryData = "uTRLyNkKTaFUxmJtHPlYoA==";
            private string key = "12345678";

            [Benchmark]
            public string EncryptDES()
            {
                Des desUtil = new Des(nodeServices);
                return desUtil.EncryptDES(data, key, 0).Result;
            }

            [Benchmark]
            public string DecryptDES()
            {
                Des desUtil = new Des(nodeServices);
                return desUtil.EncryptDES(encryData, key, 0).Result;
            }

        }
    }

    下面是控制台输出的结果,性能还是不错的

    image

  • 相关阅读:
    以太坊客户端geth的基本操作命令
    以太坊虚拟机介绍5-比较操作指令
    以太坊虚拟机介绍4-按位运算指令
    浏览器内核
    javascript 几个易错点记录
    jq常用方法
    jq事件操作汇总
    js事件总汇
    margin 负边距 的知识点
    子div撑不开父div的几种解决办法:
  • 原文地址:https://www.cnblogs.com/shanyou/p/6014352.html
Copyright © 2020-2023  润新知