代替密码构造
使用加法方式构造一种代替密码。
五元组(M,C,K,E,D)中各项如下所示:
明文
\[case\]
加密算法:
\[e(x)=x+a (mod 26) \quad a ∈ Z / (26)\]
密钥:
\[a = 5\]
密文:
\[HFYJ\]
解密算法:
\[x=e(x)-a (mod 26) \quad a ∈ Z / (26)\]
仿射密码分析
设计思想
仿射密码由加法密码和乘法密码结合构成,由于加法和乘法相互独立,可以实现更多种类的代替密码。对于仿射密码的加密过程\[e(x)=ax+b (mod 26) \quad a, b ∈ Z / (26)\]当且仅当\(gcd(a,26) = 1\)时具有唯一解(即可逆)。其中a的取值为(1,3,5,7,9,11,15,17,19,21,23,25)共12个。
(a取值为1时退化为加法密码);b取值为0到25,共26种(当b取值为0时退化为乘法密码)。在\(a = 1, b = 0\)时,相当于未加密。
- 通过C++实现仿射密码所有的\(26\times12 = 312\)种不同情况的加密过程。
- 通过Matlab对字符频率进行统计分析。
测试结果
添加一篇英文文档:Apple appkit 官方文档
在不同的仿射密码进行单表代替加密后,不同字母的出现频率等数据特征出现了明显的规律性的变化。
结果分析
原文中的各个字母的统计结果:
通过仿射密码加密后各个字母频数变化统计
由于字母数量较多,只给出\(A,B,Y,Z\)四个字母的统计结果。
通过对统计结果的分析,观察到单表代替密码(通过模拟,包含了仿射密码、加法密码的所有情况)的实现方式是将明文字母表中的每个字母用密文字母表中的相应字母来代替,明密文表字母存在特定且唯一的一一对应关系。
通过统计分析发现,单表代替密码(仿射密码)的密文存在明显的统计规律,同一字母在经过加密算法计算得到新的字母的词频特性存在明显规律。容易受到频率统计分析攻击。
附:代码
加密过程及字母频率统计
#include
#include
#include
#include
#include
typedef long long ll;
using namespace std;
string get_file_contents(const char *filename){
std::ifstream in(filename, std::ios::in | std::ios::binary);
if (in){
std::string contents;
in.seekg(0, std::ios::end);
contents.resize(in.tellg());
in.seekg(0, std::ios::beg);
in.read(&contents[0], contents.size());
in.close();
return(contents);
}
throw(errno);
}
int main(int argc, const char * argv[]) {
freopen("cData.txt", "w+", stdout);
string dataRead = get_file_contents(*argv);
string dataM;
ll cCountOfDataM[26] = {0};
ll dataReadLen = dataRead.size();
for(ll i = 0; i < dataReadLen; i++){
if(dataRead[i] >= 'A' && dataRead[i] <= 'Z'){
dataM += (dataRead[i] + 32);
cCountOfDataM[dataRead[i] - 65]++;
}
if(dataRead[i] >= 'a' && dataRead[i] <= 'z'){
dataM += dataRead[i];
cCountOfDataM[dataRead[i] - 97]++;
}
}
for(int i = 0; i < 26; i++){
cout<
统计图绘制
load cData.txt;
bar(cData(1,1:26));
name = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
set(gca, 'XTickLabel', name);
xti=[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 26];
set(gca,'xtick',xti,'xtickLabel',name);
title('原文件中各个字母出现情况统计');
for i = 1:26
hold on;
figure;
bar(cData(1:313,i));
axis([1 313 0 3500]);
end