CryptoSharp: Step 1

C#入门实践:Windows桌面加密器 CryptoSharp

Step 1 BASE64/编码/DLL

by Pixel Frame

GitHub: CryptoSharp
源码在文中基本不再出现。

0x00 前期准备

本着由浅入深、由简入繁、Top Down的原则,首先为Visual Studio选择一个好看的配色方案和合适的字体(什么狗P逻辑)。
个人还是比较喜欢深色配色,奈何Color Theme Editor插件中没有Monokai配色,自己改一个又太累了(),所以直接选择了Dark with Light Editor。
字体上的话,用Font Link把Consolas和微软雅黑链接是一个简单快捷的选择。思源的等宽字体感觉太宽了,和中文混排看起来十分诡异。原生的中英文混排等宽字体其实非常少,比如说新宋体()。首推的还是Belleve大的更纱黑体,还有一个经典选择自然是文泉驿等宽微米黑和文泉驿等宽正黑

0x01 BASE64与编码

作为一个加密器自然需要考虑各种各样的编码问题,虽然说也有很多场合把BASE64称作加密,但其本质只是把不可显示的ASCII码转换到了可显示部分。C#的Convert类中自带了BASE64转换,所以可以直接调用(本篇完,下面没有了)。

然而,要自己实现一遍~(我写的比库函数好得多.png)。

C#所有文本都是Unicode(UTF-16LE),即对应C++中的16位字符wchar_t,不能和C++一样将工程设置为多字节(UTF-8/ANSI等)。这对于进行加解密操作其实是不太方便的,BASE64是针对8位的byte(unsigned char)进行操作的,因此我们需要自己构建一个C++的std::string来方便操作。当然,加密算法中大量bit级的操作其实都不适合软件编程,相比之下用HDL作专用硬件会方便很多。关于位操作的问题会在DES中更多涉及。

ByteString

一个好用的string类需要哪些东西是很显然的,动态分配/截取/查找/运算符重载...当然,我的目标是够用就行,需要新的功能时再行添加。C#的List<>和数组十分强大,可以直接通过AddRange(), ToArray(), ToList()等一系列方法进行转换和增加,因此其实就是对List<byte>做一个二次封装。
List<byte>保存字符数据,重载+运算符,构造函数,定义索引器[],外加Set/GetBytes()ToString()方法。这样一个简单可用的ByteString类就完成了。
在之后可能还会加入移位等的功能,在遇到时再行讨论。

BASE64

BASE64的加解密并不复杂,简单来说就是每三个bytes进行一次替换,不足的地方用=替换。那么,这里就直接从一份C++代码进行改写。将C++中的char全部改为byte类型,通过Encoding获取字符的ASCII码,这里只要采用多字节代码页(ANSI/UTF-8/GBK/BIG5)都是没有问题的,结果都是相同的ASCII码。当然Encoding会损失一定的性能,通过硬编码将对应ASCII码写入程序能提高一定的性能,当然既然选择了C#对性能也不做过分的追求了。
一般而言会将查找表设为全局常量,然而并没有找到如何声明一个const数组,那么就只好使用static readonly,效果似乎是相同的。

static readonly byte[]  base64Table = Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 +/");
static readonly byte    base64Pad = Encoding.UTF8.GetBytes("=")[0];
static readonly byte[]  base64PadD = Encoding.UTF8.GetBytes("==");
static readonly int[]   decodeTable =
    {
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -2, -1, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,
    -2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,
    -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2
    };

加解密过程就不作详细解释了,再来说说编码的问题。基本的加密方法的输入是byte[]输出是string(UTF-16LE),但一般而言输入会是一个字符串并且会有各种编码的可能(当然作为C#程序一般获取到的都会是UTF-16LE)。高级语言的好处就在于各种功能都有现成的封装,相比C++的MultiByteToWideChar()函数和USES_CONVERSION宏,C#的Encoding类要方便很多,支持的编码可以在微软的开发文档中找到。核心的EncryptDecrypt方法使用byte[]作为输入/输出,再进行string的重载并且添加指定编码参数。

public static String Encrypt(byte[] bPlain);

public static String Encrypt(String strPlain, String coding);

public static String Encrypt(String strPlain, int coding);

public static byte[] Decode(String strEnc);

public static String DecodeEncoding(String strEnc, String coding);

public static String DecodeEncoding(String strEnc, int coding);

0x02 解决方案与DLL

为了方便管理,将各个加密算法作为DLL项目添加至解决方案中。DLL的接口方法会逐渐完善。最终CryptoSharp将只需要调用DLL的接口,本身则是WinForm UI为主。
C#中同一解决方案项目、.NET库、外部DLL都只需要在添加引用即可,包括C++ COM组件DLL也是可以直接使用的。


次回予告:DES AND SHIFTING


END_OF_PART_2

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,517评论 18 139
  • 概述 之前一直对加密相关的算法知之甚少,只知道类似DES、RSA等加密算法能对数据传输进行加密,且各种加密算法各有...
    Henryzhu阅读 2,994评论 0 14
  • 字符是用户可以读写的最小单位。计算机所能支持的字符组成的集合,就叫做字符集。字符集通常以二维表的形式存在。二维表的...
    刘惜有阅读 8,045评论 2 14
  • 深而有力的呼吸:左侧腰部疼,无情绪 发泄与释放: 1,该做的不敢做,怕被说、被指责无用;➡️ 不做离开了道➡️ 做...
    元丽Sarah蓝风暴阅读 406评论 0 1
  • 本周项目实施过程中暴露了很多问题, 1. 自己这个不懂技术的PM,一定限制了项目的进展。这个开始我就提醒过老板我不...
    韦陀阅读 152评论 0 0