基于M2加密算法深度解读

描述

这个加密类很容易实现和使用。如果你需要加密字符串,如密码、汽车牌号等,就可以使用这个个快捷、简单、安全的方式。只要不暴露加密 KEY, 就会很安全。建议KEY 的长度最少为 12 个包含大小写的字符。
使用代码

首先下载源代码,将其中的类插入你的命名空间。然后你可以初始化类的对象。
加密
以下代码块是如何使用 key 变量YourEncryptionKey 加密字符串变量 YourTextString 的简单例子。

M2encryption.Key = YourEncryptionKey;M2encryption objEncrypt = new M2encryption();objEncrypt.ClearTekst = YourTextString; objEncrypt.Encrypt(); if (objEncrypt.errorState != -2) { MessageBox.Show(objEncrypt.EncryptedTekst);}

在做进一步处理前检查属性 objEncrypt.errorState 有无错误
errorState-1:
这意味着加密的文本包含 ASCII 以外的字符。在加密前,这些字符被更改为 "?"
errorState-2:
没有提供加密 key。加密过程会中断。
解密:

M2encryption.Key = YourEncryptionKey;M2encryption objEncrypt = new M2encryption();objEncrypt.EncryptedTekst = YourTextString; objEncrypt.Decrypt(); if (objEncrypt.errorState != -2) { MessageBox.Show(objEncrypt.ClearTekst);}

随机化
将属性 Randomization 设置为 true,运行多次,同一个加密key 和平面文本会产生不同的加密文本

M2encryption.Randomization = true;

快捷模式
设置为Fastmode 模式会让加密/解密快捷,但是安全性会降低。如果你要加密小字符串,不应该启用该模式。如果加密很大的文件,可以。
注意,解密和加密的模式应该相同。

M2encryption.Fastmode = true;

算法的内部工作原理
外部循环和内部循环
算法包含外部和内部循环。外部循环迭代次数,内部循环迭代平面文本中每个字符。
自变异内部和外部 key
自变异内部key
此 key 在内部加密流程中使用。key 中每个字母都哟牛股加密平面文本中对应的位置。当 key 的字符串结束后,该流程会使用自变异的key 版本继续进行,直至所有平面文本都加密完。看图1 说明。子变异的内部 key 标记为蓝色。

安全性

Fig1. 上述的key永远不会重复
自变异外部 key
用户输入key 后,自变异的外部key 会初始化。该key会用于外部循环并在每次开始自改变。该key的目的是为每轮生成唯一的映射矩阵并在这些轮中初始化自变异内部key。映射数组在内部循环中的加密流程中使用。
6 轮迭代的key 自变化的例子:

安全性

函数 shuffleArr() 将自变异key作为输入。根据key, 它会在 arrayint[] 中得出类似随机顺序的映射数字。函数每次调用,key 就会自变异,从而创建出新的唯一映射数组。
函数 shuffleArr():

private void shuffleArr(int state){ int keyStep = 0; byte keyChar; bool emptyFound; int retning = 1; long refIndex = 1; double floatValue; int intPart; double fraPart; mutKey_o = selfMutateKey(mutKey_o, 3, state,1); for (int i = 0; i < 95; i++) map[i] = 0; //nulstil arr for (int i = 1; i < 96; i++) { if (retning == 1) retning = 0; else retning = 1; //håndter key if (keyStep > mutKey_o.Length - 1) keyStep = 0; keyChar = (byte)mutKey_o[keyStep]; refIndex = i + (int)keyChar; if (refIndex > 95) { if (refIndex - 95 <= 95) refIndex = refIndex - 95; else { floatValue = refIndex / 95.0; intPart = (int)floatValue; fraPart = floatValue - intPart; if (fraPart == 0.0) fraPart = 1.0; refIndex = Convert.ToInt32(95 * fraPart); } } refIndex--; //pga arr 0- 94 if (map[refIndex] == 0) map[refIndex] = i; else { emptyFound = false; do { if (retning == 1) { refIndex++; if (refIndex > 94) refIndex = 0; if (map[refIndex] == 0) { map[refIndex] = i; emptyFound = true; } } else { refIndex--; if (refIndex < 0) refIndex = 94; if (map[refIndex] == 0) { map[refIndex] = i; emptyFound = true; } } } while (emptyFound == false); } keyStep++; } for (int i = 0; i < 95; i++) { for (int k = 0; k < 95; k++) { if (map[k] == i + 1) { mapRev[i] = (k + 1); break; } } } }

内循环加密流程
Step 1:
整个文本都需要经过函数 chainChangeChars() 处理
文本会被从头到尾来回扫描,文本中每个字母都根据左边的相邻字符(在回来的时候根据右边的相邻字母)更改。如果一个字母更改,每个单独的字母也会随之更改。每个更改的字符会跟映射 arrayint[] 图重新映射。
这是我解决问题的公式:
示例文本 "ABCD"
A 是 B 的左边相邻字母

安全性


在相反的流程中

安全性

然后重新映射:
Y = map[X]
最后:
B 被替换为 Y
文本成为 "AYCD" (其中 Y 是个持有真正字母的变量)
原先的 B现在存储在 Y 内。可以通过 Y 和 A 还原
Step 2:
这个步骤是个流程的开始,会根据自变异的内部key 更改文本中每个字母,如图一所示。
首先生成一个种子。对于每个要更改的字母,下个文本的十进位 ascii 值会在 variabelseedC 中累计。看第一行代码:

seedC = seedC + (byte)Convert.ToChar(key[keyIndexC]);keyIndexC++; if (keyIndexC > lenKey - 1){ keyIndexC = 0; mutKey_i = selfMutateKey(key,2,1,2);}

Step 3:
生成引用索引号.
步骤 2 中的种子现在用作函数 createRefIndex() 的输入
在这个函数中,种子经过这个公式:
种子除以 95
将小数的整数部分更改为 0
结果乘以 95
代码如下:

refIndex = seed; if (refIndex > 95){ if (refIndex - 95 <= 95) refIndex = refIndex - 95; else { floatValue = refIndex / 95.0; intPart = (int)floatValue; fraPart = floatValue - intPart; if (fraPart == 0.0) fraPart = 1.0; refIndex = Convert.ToInt32(95 * fraPart); }}

得到的 refIndex 将总是一个 [1 - 95] 的整数。
Step 4:
在最后一个步骤中,字符更改为加密文本中的最终字符
字符的索引添加到 therefIndex-1
最后的结果通过 arrayint[] 图重新映射

tegnChanged = tegn + (refIndex - 1); if (tegnChanged > 95) tegnChanged = tegnChanged - 95;tegnChanged = map[tegnChanged - 1];

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分