维吉尼亚(Vigenere)密码算法(Javascript实现加密与解密)
  传统加密技术对于当今的⽹络安全发挥不了⼤作⽤,但每⼀本讲述密码学的书的开头都会率先介绍它们,因为它们是密码学的基础,是密码学的历史。Vigenere密码就是⼀种传统加密技术,它是多表代换密码,能够有效改进单表代换密码的词频分布特征问题。详细介绍请参考密码学相关书籍。
  ⼏乎每⼀本密码学的书在讲述Vigenere密码的章节都会有这么⼀个《Vigenere代换表》⽤户讲解Vigenere密码机制:
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
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 A
C D E F G H I J K L M N O P Q R S T U V W X Y Z A B
D E F G H I J K L M N O P Q R S T U V W X Y Z A B C
E F G H I J K L M N O P Q R S T U V W X Y Z A B C D
F G H I J K L M N O P Q R S T U V W X Y Z A B C D E
G H I J K L M N O P Q R S T U V W X Y Z A B C D E F
H I J K L M N O P Q R S T U V W X Y Z A B C D E F G
I J K L M N O P Q R S T U V W X Y Z A B C D E F G H
J K L M N O P Q R S T U V W X Y Z A B C D E F G H I
K L M N O P Q R S T U V W X Y Z A B C D E F G H I J
L M N O P Q R S T U V W X Y Z A B C D E F G H I J K
M N O P Q R S T U V W X Y Z A B C D E F G H I J K L
N O P Q R S T U V W X Y Z A B C D E F G H I J K L M
O P Q R S T U V W X Y Z A B C D E F G H I J K L M N
P Q R S T U V W X Y Z A B C D E F G H I J K L M N O
Q R S T U V W X Y Z A B C D E F G H I J K L M N O P
R S T U V W X Y Z A B C D E F G H I J K L M N O P Q
S T U V W X Y Z A B C D E F G H I J K L M N O P Q R
T U V W X Y Z A B C D E F G H I J K L M N O P Q R S
U V W X Y Z A B C D E F G H I J K L M N O P Q R S T
V W X Y Z A B C D E F G H I J K L M N O P Q R S T U
W X Y Z A B C D E F G H I J K L M N O P Q R S T U V
X Y Z A B C D E F G H I J K L M N O P Q R S T U V W
Y Z A B C D E F G H I J K L M N O P Q R S T U V W X
Z 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
  加密过程很简单,就是给定密钥字母x和明⽂字母y,密⽂字母是位于x⾏和y列的那个字母。这样就决定了加密⼀条消息需要与消息⼀样长的密钥字符串,通常,密钥字符串是密钥词的重复。
  以《密码编码学与⽹络安全——原理与实践》中的例⼦来作为本⽂的例⼦。⽐如密钥词是deceptive,消息是“we are discovered save yourself”,那么加密过程如下:
deceptivedeceptivedeceptive(密钥字符串)
wearediscoveredsaveyourself(消息)
ZICVTWQNGRZGVTWAVZHCQYGLMGJ(密⽂)
  密⽂中的第⼀个字母“Z”是怎么得来的?从Vigenere代换表中,以密钥字符串中的“d”为⾏,消息中的“w”为列的那个字母就是“Z”了。
  使⽤查表的⽅式多加密⼏次就能很轻易地总结出规律:将A~Z以0~25编号,那么加密过程就是,在代换表的第⼀⾏中到消息字母,如“w”,然后向后移动d(即3)次,所得的字母就是密⽂了。如果数到末位,那么下⼀次移位就从头(即A)继续。也就是说,可以将A~Z 看成⼀个环,加密过程就是定消息字母后,将指针往环的某个特定⽅向移位,次数就是密钥字母所代表的数字。这其实是⼀个模26的过程。
  扩展⼀下,以上加密仅能对26个字母进⾏加密,⽽且不能区分⼤⼩写。但其实英⽂中除了字母外,还有标点符号,还有空格。如果考虑到⼤部分英⽂字符,那么Vigenere代换表将⽐较⼤,⽽且有点浪费空
间的嫌疑。如果假设能被加密的字符有N个,如果把这N个字符建成⼀个环,那么加密过程就是模N的过程,即,C(i)=(K(i)+P(i))modN,其中K、C、P分别代表的是密钥空间、密⽂空间、消息(明⽂)空间。
  ⽹络上有⼈⽤C实现了这个加密算法,⼏乎都是使⽤查代换表的⽅法。虽然可以程序⽣成代换表,但所⽣成的代换表太有规律了。以下我⽤Javascript实现了⼀次,使⽤的是模的⽅法,感觉灵活度更⼤,占⽤的空间肯定也更⼩(时间效率尚未估计)
1var Vigenere = {
2    _strCpr: 'abcdefghijklmnopqrstuvwxyz_12345 67890.ABCDEFGHIJKLMNOPQRSTUVWXYZ',//可以将此字符串的顺序打乱点,或者添加更多字符
3    _strKey: function(strK,str){//⽣成密钥字符串,strK为密钥,str为明⽂或者密⽂
4var lenStrK = strK.length;
5var lenStr = str.length;
6if(lenStrK != lenStr){//如果密钥长度与str不同,则需要⽣成密钥字符串
7if(lenStrK < lenStr){//如果密钥长度⽐str短,则以不断重复密钥的⽅式⽣成密钥字符串
8while(lenStrK < lenStr){
9                    strK = strK + strK;
10                    lenStrK = 2 * lenStrK;
11                }
12            }//此时,密钥字符串的长度⼤于或等于str长度
13            strK = strK.substring(0,lenStr);//将密钥字符串截取为与str等长的字符串
14        }
15return strK;
16    }
17 }
18
19 Vigenere.lenCpr = Vigenere._strCpr.length;
20
21 Vigenere.Encrypt = function(K,P){//加密算法,K为密钥,P为明⽂
22    K = Vigenere._strKey(K,P);
23var lenK = K.length;字符串长度为0
24var rlt = '';
25var loop = 0;
26for(loop=0; loop<lenK; loop++){
27var iP = Vigenere._strCpr.indexOf(P.charAt(loop));
28if(iP==-1) return '本算法暂时不能对字符:' + P.charAt(loop) + '进⾏加密'; 29var iK = Vigenere._strCpr.indexOf(K.charAt(loop));
30if(iK==-1) return '密钥中包含⾮法字符:' + K.charAt(loop);
31var i = (iP + iK) % Vigenere.lenCpr;
32        rlt = rlt + Vigenere._strCpr.charAt(i);
33    }
34return rlt;
35 };
36
37 Vigenere.DisEncrypt = function(K,C){
38    K = Vigenere._strKey(K,C);
39var lenK = K.length;
40var rlt = '';
41var loop = 0;
42for(loop=0; loop<lenK; loop++){
43var iK = Vigenere._strCpr.indexOf(K.charAt(loop));
44if(iK==-1) return '密钥中包含⾮法字符:' + K.charAt(loop);
45var iC = Vigenere._strCpr.indexOf(C.charAt(loop));
46if(iK > iC){
47            rlt += Vigenere._strCpr.charAt(iC + Vigenere.lenCpr - iK);
48        }
49else{
50            rlt += Vigenere._strCpr.charAt(iC - iK);
51        }
52    }
53return rlt;
54 };

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。