#Convert.FromBase64String
Explore tagged Tumblr posts
Text
How to convert base64 string format of excel file into DataTable form of data type using C#
How to convert base64 string format of excel file into DataTable form of data type using C#
In this article, We learn how to convert base64 string format of excel file into Data Table form of data type using C#. I will show how to do it, and just follow the steps clearly. For more updates please do Subscribe via Email: Type your email… Subscribe I encounter this task and make me sleepless during night because I can’t see any reference in other blog resources. Basically the logic…
View On WordPress
#Aspose#Aspose.Cells#Aspose.Cells.LoadOptions#Aspose.Cells.Worksheet#base46stringToDataTable#base64#C#Conversion of Base64String to Bytes#Conversion of JSON to Model object#Conversion of worksheet to datatable#Convert.FromBase64String#DataTable#JsonConvert.DeserializeObject#worksheet.Cells
0 notes
Text
.Net Core后端,静态HTML前端,Websocket通信,为Config.json添加配置
书接上回
折腾了防火墙之后我决定把Shadowsocks Sever也弄一下,以前两台服务器上装的都是libev版,所有人都共用的一套端口和密码。libev版想配置多用户还是挺麻烦的,但是又不是很想换成Go或者Python版,毕竟想到有性能差距还是有些不舒服。后来在SS的官方Repo里面发现了Rust版的,还支持简单的多用户配置,就很棒,照着编译指南就开始了操作。库文件装好,工具装好就开干,将近一个小时过去了,收获到了一条错误信息,再查,再干,又一个小时过去,又换了一条错误信息。网上找了一些前人的编译经验,看了看,还是没找到到底是个什么问题。最后忘记在哪里看到的帖子,之后才发现是我的VPS小鸡配置根本不够编译出来这东西,512的RAM太紧巴了。这也太惨了,好不容易找到一个不错的Server版本,但是却编译不出来。机智的我又去看了一下rust分支的release页面,发现有编译好的bin,瞬间感觉浪费了很多生命。照着指南,改了一下Config.json文件,基本上还是照着之前的libev版来的,然后Systemd写了一下,妥妥的跑了起来。
再发出去一张问卷,把密码和端口都收集一下,绑定到人,这样管理起来就很舒服,但是每次手动去改Config.json添加服务器真的很恶心,而且在外面用手机的话没有WinSCP这种图形化软件可以用,添加配置就只能靠SSH连上去用vim,体验极差。联想到之前做过一个百度AI的人脸相似度比较的Demo玩,在C#里面用JSON还是很方便的,就萌生了写一个程序来搞这个事情的念头。
程序基本上就是照着这个纯静态HTML 与 C# Server 进行WebSocket 连接的写法写的,尽量都从简,写好的CS两端的代码都在这个Repo。
前后端交互结构
客户端向服务器发起连接请求
连接成功之后服务器端向客户端发送八字节随机数字作为Challenge,code=1
byte[] random = new byte[8]; using (var rng = new RNGCryptoServiceProvider()){ rng.GetNonZeroBytes(random); }
客户端收到Challenge消息之后用预共享密钥对Challenge消息进行HMACSHA256生成消息认证码,发回服务器,code=2
服务器再将客户端发来的值与自己计算出的值比对,并发回认证结果,code=3
using (HMACSHA256 hmac = new HMACSHA256(Encoding.UTF8.GetBytes(Psk))) { byte[] hashValue =hmac.ComputeHash(Encoding.UTF8.GetBytes(_challengeMsg)); var res =BitConverter.ToString(hashValue); if (res.Replace("-", string.Empty).ToLower() == msg.content) { _authenticated = true; Send(JsonConvert.SerializeObject(new Message { code = 3,content = "authentication succeed"})); Console.WriteLine("[{0}][{1}]authentication succeed.", DateTime.Now, _socketInfo); }else { Send(JsonConvert.SerializeObject(new Message { code = 0, content = "authentication failed" })); Console.WriteLine("[{0}][{1}]message \"authentication failed\" sent", DateTime.Now, _socketInfo); } }
认证成功后客户端将配置信息发往服务器,code=4
服务器进行处理,并返回结果(添加成功/失败),客户端将信息展示在前端> 过程中所有服务器发往客户端的提示消息code均设置为0,客户端不需要处理,只需将消息展示在HTML中。 ## 一些细节
由于要在公网上传输端口号和密码,如果不加密的话就会带来极大的风险,Wireshark就能直接抓到明文包,所以我将客户端发往服务器的数据包都是用AES加密。
function encrypt(json, psk) { plaintext = CryptoJS.enc.Utf8.parse(JSON.stringify(json)); let key = CryptoJS.enc.Utf8.parse(psk.padEnd(32, '0')); let iv = CryptoJS.enc.Utf8.parse(psk.padEnd(16, '0')); let encrypted = CryptoJS.AES.encrypt(plaintext, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); return CryptoJS.enc.Base64.stringify(encrypted.ciphertext); }
客户端中使用CryptoJS的加密函数
try{ byte[] keyArray = new byte[32]; byte[] iv = new byte[16]; Encoding.UTF8.GetBytes(Psk.PadRight(16, '0')).CopyTo(iv, 0); Encoding.UTF8.GetBytes(Psk.PadRight(32, '0')).CopyTo(keyArray, 0); using (var aesAlg = new AesCryptoServiceProvider()){ aesAlg.Key = keyArray; aesAlg.IV = iv; aesAlg.Padding = PaddingMode.PKCS7; var toDecryptArr = Convert.FromBase64String(rawData); ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); using (var msEncrypt = new MemoryStream(toDecryptArr)){ using (var csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Read)){ using (var srEncrypt = new StreamReader(csEncrypt)){ data = srEncrypt.ReadToEnd(); } } } } } catch (Exception){ Send(JsonConvert.SerializeObject(new Message { code = 0, content = "failed to decode." })); Console.WriteLine("[{0}][{1}]failed to decode.", DateTime.Now, _socketInfo); }
服务端的解密处理
服务端程序编码、调试、测试完成后,就需要部署到服务器,最开始使用的FDD模式(部署模式介绍),后来直觉告诉我使用SCD模式会更舒服,我就选了SCD模式将整个程序以及运行库打包传到服务器上运行。
作为一个Sever程序,就要在程序后台运行,但是.Net Core在Linux上Daemon运行支持不大完善,ServiceHost方法也很复杂,我就没有去研究,将目光转向了Systemd。编写好service文件,运行,可程序却无法成功在Systemd管理下正常运行,一直光速退出。后来才发现是用来暂停主线程的ReadKey()的问题,将他改成了个死循环,程序在Systemd下正常运行了,但是却一直占用大量的CPU,又进行了改进,在循环中加一个Sleep,然后委托一个Ctrl+C,其中进行server的stop和退出提示,基本上就完成了。
由于后端使用的是较为简单的websocket-sharp,没有办法直接使用WSS,然而我最终是把这个客户端用在了一个启用SSL的网站上,几乎所有的新版现代浏览器都会阻止ws://协议再https下运行,所以说基本上就没法用了。但是重新改后端,弄证书工作量太大太麻烦,我便选择了使用Nginx反代,正好还能直接挂到Cloudflare上,用起来还更加放心。
运行
The End
0 notes