本文旨在介绍一种字符替换加密方法及其图形用户界面(GUI)的实现。这种方法主要用于教学和学习目的,不应用于任何生产环境。本文将详细说明如何使用文本框选择和着色文本、线程以及从线程引用它们未创建的GUI控件。
这是作者在操作系统安全课程中的一个项目作业。作者使用了在维基百科()和CodeProject网站上找到的代码。该项目使用Visual Studio 2015构建。
要使用演示应用程序,可以打开一个纯文本文件或在输入框中输入自己的纯文本。如果选择'Table'而不是'Public Key',请意识到只有一小部分非字母数字字符将被加密。如果想要处理更广泛的特殊字符集,只需将它们添加到'unencrypted_char_table'或'encryption_table'中。
选择'Encrypt'或'Decrypt',然后点击'Next'逐步执行每个字符,或者点击'Run'观看整个过程,点击'Stop'停止运行,点击'Reset'重新开始。
如果想要将加密后的输出保存到文件中,请点击'Save As'按钮。可以在当前会话中重新加载保存的文件进行解密。请注意,每次运行程序时都会生成一组新的密钥。
'1st Prime'和'2nd Prime'选择是用于密钥生成的两个不同的“随机”素数。这些值故意保持较小,以便可以使用简单的计算器来重现结果。在现实世界中,公钥加密使用非常大的素数。
加密过程是简单且有注释的。以下是C#代码示例:
private string Encrypt(string _inChar) {
string _out = "\n";
// 公钥加密?
if (radioButton_public_key.Checked) {
input_p = _inChar[0];
BigInteger _mod = BigInteger.ModPow(input_p, public_key_e, public_key_n);
return _mod.ToString("00000");
}
// 目前正在加密数字?
if (unencoded_digits) {
// 目前正在处理未加密的数字
if (digits_table.Contains(_inChar)) {
// 是的,返回数字字符
_out = _inChar;
} else {
// 不,输入字符不是数字 - 已经到达数字序列的末尾
unencoded_digits = false;
// 结束未加密数字序列
_out = "^^";
if (unencrypted_char_table.Contains(_inChar)) {
// 是的,添加字符到输出
_out += _inChar;
} else if (encryption_table.ContainsKey(_inChar.ToString())) {
// 是的,查找字典中的密码字符
_out += encryption_table[_inChar].ToString();
}
}
} else {
// 当前不是加密数字
if (digits_table.Contains(_inChar)) {
// 开始未编码数字序列
unencoded_digits = true;
_out = "^^" + _inChar;
} else if (unencrypted_char_table.Contains(_inChar)) {
_out = _inChar;
} else if (encryption_table.ContainsKey(_inChar.ToString())) {
// 查找字典中的密码字符
_out = encryption_table[_inChar].ToString();
}
}
if (unencoded_digits) {
// 输入是输入的最后一个字符吗?
string _inText = GetControlProperty(richTextBox_input, "Text").ToString();
if (inputCursor + _inChar.Length >= _inText.Length) {
// 是的,它是最后一个字符
_out += "^^";
}
}
return _out;
}
private string Decrypt(ref string _inChar) {
string _out = string.Empty;
// 公钥加密?
if (radioButton_public_key.Checked) {
if (_inChar == "\n") return _inChar;
input_p = BigInteger.Parse(_inChar);
char _mod = (char)BigInteger.ModPow(input_p, private_key, public_key_n);
return _mod.ToString();
}
// 输入字符是0-9的数字吗?
if (digits_table.Contains(_inChar[0])) {
if (unencoded_digits) {
// 是的,未编码数字
_inChar = _inChar.Substring(0, 1);
return _inChar;
} else {
// 不,这些是密码数字
// 获取两个字符
// 解析ASCII数字
int _cipherNumber;
if (int.TryParse(_inChar.Substring(0, 2), out _cipherNumber)) {
if (encryption_table.ContainsValue(_cipherNumber)) {
_inChar = _inChar.Substring(0, 2);
return encryption_table.FirstOrDefault(x => x.Value == _cipherNumber).Key.ToString();
}
}
}
}
if (unencrypted_char_table.Contains(_inChar[0])) {
// 未编码字符
_inChar = _inChar.Substring(0, 1);
return _inChar;
} else if (_inChar[0] == '^') {
if (_inChar.Substring(0, 2) == "^^") {
// 切换未编码状态
unencoded_digits = !unencoded_digits;
// 丢弃前两个字符,返回第三个字符
return _inChar.Substring(2, 1);
}
}
_inChar = _inChar.Substring(0, 1);
return _inChar;
}