第2章 古典密码体制
1.当k=5,b=3时,用仿射密码加密这些字符:WO SHI XUESHENG 解:加密公式:c=e(p)=5p+3(mod26)
首先转化把这些字母转换成数字:22,14,18,7,8,23,20,4,18,7,4,13,6 然后加密
;)26(mod 716231215232514171215219)26(mod 3333333333333613471842023871814225??????????????????????????????????????=??????????????????????????????????????=??????????????????
????????????????????+??????????????????????????????????????H Q X M P X Z O R M P V G 所以,加密后为:GV PMR OZXPMXQH 。
2.使用Vigenere 方案,给出密文:ZICVTWQNGRZGVTWA VZHCQYGLMGJ ,找出对应下列明文的密钥:Wearediscoveredsaveyourself 。
解:
明文:W e a r e d i s c o v e r e d s a v e y o u r s e l f 密文:Z IC VTWQNGR ZGVTWAVZH CQ YGLMGJ 将字幕转化成数字,再计算。
结果密钥为:3 4 2 4 15 19 8 21 4
3.分析Vigenere 密码体制的安全性,并编程实现Vigenere 密码算法。 解:Vigenere 密码的强度在于对每个明文字母有多个密文字母对应,因此该字母的频率信息是模糊的。实际上,维吉尼亚(Vigenere )密码是一种多表加密算法,在密文的不同位置出现的字符通常不是以同样的方式加密的,但它是一种周期密码,如果两个同样的字符出现的间隔固定,并且为密钥长度的倍数,则它们将以同样的方法进行加密。 Vigenere 算法c 语言的简单实现
#include
main()
{
int i,j,m,n,c,k,Ming_length,Key_length;
char vigenere_table[26][26];
char Key[200],Ming[500] ,Mi[200],s[26][26];
printf("Vigenere Table:\n");
for(j=0;j<=25;j++)
{
printf("%c\n",'a'+j);
for(i=0;i<=25;i++)
{
vigenere_table[i][j]='A'+(i+j)%26;
printf("%c",vigenere_table[i][j]);
}
}
printf("\n");
for(i=0;i<=25;i++)
{
printf("%c",'a'+i);
}
printf("\n");
printf("请输入明文:\n");
gets(Ming);
printf("请输入密钥: \n");
gets(Key);
Ming_length=strlen(Ming);
Key_length=strlen(Key);
printf("\n");
k=0;
printf("明文是\n");
do
{
for(j=k;j { int m=Ming[j]; int n=Key[j-k]; printf("%c",vigenere_table[m-97][n-97]); } k+=Key_length; }while(k getch(); } 4.分析Hill密码体制的安全性,并编程实现Hill密码算法。 解:Hill密码技术可以较好地抗击统计分析攻击,但在面对已知明文的攻击就很容易被破译,特别是在已知密钥矩阵行数的情况下。 算法实现: #include #include #include #define NUM 20 #define NUM2 1000 int main() { int i,j,k=0,n,p[NUM]; printf("阶数: "); scanf("%d",&n); printf("\n密钥: "); int q[NUM][NUM]; for(i=0;i { scanf("%d",&p[i]); } for(i=0;i { for(j=0;j { q[i][j]=p[j+k]; //printf("%d ",q[i][j]); if((j+1)%n==0) { k+=n; // printf("\n"); } } } char word[NUM2]; int length,word2[NUM2][1]; printf("明文: "); scanf("%s",word); length=strlen(word); for(i=0;i { //printf("word: %c",word[i]); word2[i][0]=word[i]-97; //printf("word2:%d",word2[i][0]); } i=0,j=0,k=0; int count=0,temp[NUM2][1],temp2[NUM2][1]; for(i=0;i { for(j=0;j<1;j++) { temp[i][j]=0; temp2[i][j]=0; } } k=strlen(word); //printf("K: %d\n",k); int z=0; j=0; printf("密文: "); while(z { temp[j][0]=word2[j+count][0]; //printf("temp:%d\n",temp[j][0]); j+=1; if(j%n==0) { //printf("dffsf"); int i,s; for(i=0;i { for(int u=0;u<1;u++) { for(s=0;s { temp2[i][0]+=q[i][s]*temp[s][0]; temp2[i][0]=(temp2[i][0])%26; } printf("%c",temp2[i][0]+65); } } for(i=0;i { temp2[i][0]=0; } count+=n; z+=1; } if(j%n==0) j=0; //printf("%d \n",z); } printf("\n"); system("pause"); } 5.分析Vernam 密码体制的安全性,并编程实现Vernam 密码算法。 解:Vernam 密码技术,它是一种代数密码技术。其加密方法是,将明文和密钥分别表示成二进制序列,再把它们按位进行模2加法。为了增强Vernam 密码技术的安全性,应该避免密钥的重复使用。假设我们可以做到:密钥是真正的随机序列;密钥的长度大于或等于明文的长度;一个密钥只使用一次。那么Vernam 密码技术是经得起攻击的考验的。 BOOL SettleString(char *src,DWORD len) { if (src==NULL) return FALSE; for (DWORD i=0;i { src[i]=src[i]^0x76; } return TRUE; } 6.英文字母a,b,c,…,z 分别编码为0,1,2,3,4,…,25,已知Hill (希尔)密码中的明文分组长度为2,密钥K 是Z26上的一个二阶可逆方阵,假设密钥为hell,明文welcome ,试求密文。 解:hell 转化成数字为:10,4,11,11.因为分组长度为2,所以,密钥矩阵K 为:?? ? ???1111410 将明文转化成数字:22,4,11,2,14,12,4 明文矩阵M 为:?? ??? ? ??? ???441214211422,则密文C =MK (mod26) 结果为:??????????????8661214224转化成字母,密文为:E C C O M G G