博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
传统加密技术续-Hill Vigenere Vernam
阅读量:6166 次
发布时间:2019-06-21

本文共 5550 字,大约阅读时间需要 18 分钟。

在上篇文章中,讲述了一些加密解密的概念以及Caesar、单表替换密码、Playfair密码。在这篇文章中主要涉及Hill密码,Vigenere密码,Vernam密码,置换技术。

Hill密码

希尔密码(Hill Cipher)是运用基本矩阵论原理的替换密码,由Lester S.Hill在1929年发明。该加密算法将m个连续的明文字母替换成m个密文字母,这是由m个线性等式决定的,在等式里每个字母被指定为一个数值(a=0,b=1,....,z=25)。例如m=3,系统可以描述为: c1=(k11p1+k21p2+k31p3)mod26 c2=(k12p1+k22p2+k32p3)mod26 c3=(k13p1+k23p2+k33p3)mod26 用行向量和矩阵表示如下:

这里C和P是长度为3的行向量,分别代表密文和明文,K是一个3*3矩阵,代表加密密钥。运算按模26执行。相应的解密公式为P=CK-1mod26。

代码如下:

package com.general.encryanddecode;import java.util.Arrays;import java.util.Random;/*** Hill算法* 希尔密码(Hill Cipher)是运用基本矩阵论原理的替换密码,由Lester S.Hill在1929年发明.下面实现简单的Hill算法的加密解密** @author generalandroid* **/public class HillTest {    private int[][] k= new int[3][3];//{17,17,5,21,18,21,2,2,19};    /**逆矩阵**/    private int[][] d_k=new int[3][3];//{4,9,15,15,17,6,24,0,17}    private String table="ABCDEFGHIJKLMNOPQRSTUVWXYZ";    private int p_length;    private String pContent;    private String cContent;    private int[] p_int;    private int[] c_int;    public HillTest(String cotent){        System.out.println("原文:"+cotent);        pContent=cotent;        p_length=pContent.length();        initKAndDK();        initPContent();    }    private void initKAndDK(){        //正向矩阵        k[0][0]=17;k[0][1]=17;k[0][2]=5;        k[1][0]=21;k[1][1]=18;k[1][2]=21;        k[2][0]=2; k[2][1]=2; k[2][2]=19;        //逆向矩阵        d_k[0][0]=4; d_k[0][1]=9; d_k[0][2]=15;        d_k[1][0]=15;d_k[1][1]=17;d_k[1][2]=6;        d_k[2][0]=24;d_k[2][1]=0; d_k[2][2]=17;    }    //对明文做初始处理    private void initPContent(){        if(p_length%3==2){            pContent=pContent+"Z";        }else if(p_length%3==1){            pContent=pContent+"ZZ";        }        if(p_int==null){            p_int=new int[pContent.length()];        }        int i=0;        System.out.println(pContent.toCharArray());        for(char c:pContent.toCharArray()){            p_int[i]=table.indexOf(c);            i++;        }        System.out.println("p_int="+Arrays.toString(p_int));    }    private void encrypt(){        if (c_int==null){            c_int=new int[pContent.length()];        }        for(int i=0;i

多表代替密码

对简单单表代替的改进方法是在明文消息中采用不同的单表代替。这种方法一般称之为多表代替密码 。所有这些方法都有以下的共同特征:(1)采用相关的单表代替规则集(2)密钥决定给定变换的具体规则。

Vigenere密码

Vigenere密码:多表代替密码中最著名的和最简单的是Vigenere密码。它的代替规则集由26个Caesar密码的代替表组成,其中每一个代替表是对明文字母表移位0~25次后得到的代替单表。每个密码由一个密钥字母来表示,这个密钥字母用来代替明文字母a,故移位3次的Caesar密码由密钥值3来代表。 代码如下:

package com.general.encryanddecode;import java.util.Arrays;/*** * 多表代替密码-Vigenere * 它的代替规则集由26个Caesar密码的代替表组成,其中每一个代替表是对明文字母表移位0~25次后得到的代替单表。每个密码由一个密钥字母来表示 * ,这个密钥字母用来代替明文字母a,故移位3次的Caesar密码由密钥值3来代表。 * @author generalandroid */public class VigenereTest {    private String key;    private String pContent;    private String cContent;    private int[] key_index;    private char[] p_content;    private char[] c_key;    private char[] c_content;    public VigenereTest(String key,String content){        this.key=key;        this.pContent=content;        System.out.println("密钥:"+key);        System.out.println("原文:"+pContent);        this.key_index=new int[pContent.length()];        this.p_content=pContent.toCharArray();        this.c_content=new char[p_content.length];        initKey();    }    public static void main(String[] args){        VigenereTest vigenereTest=new VigenereTest("GEAKAAZEN","GENERALANDROIDGEAKAAZEN");        vigenereTest.encrypt();        vigenereTest.decrypt();    }    /**重新构建密钥词**/    private void initKey(){        key=key+pContent.substring(0,pContent.length()-key.length());        System.out.println("转换之后的key:"+key);        c_key=key.toCharArray();        for(int i=0;i
90){ p_index=p_index-90+'A'; //System.out.println("p_index:"+p_index); } c_content[i]=(char)p_index; } System.out.println("密文:"+new String (c_content)); } public void decrypt(){ char []t=new char[p_content.length]; for(int i=0;i

Vernam密码

Vernam密码:Vernam密码属于流密码,其加密过程是明文与密钥按位异或,解密过程是密文与密钥按位异或。

其中:pi是明文第i个二进制位,ki是密钥第i个二进制位,ci是密文第i个二进制位。

代码如下:

package com.general.encryanddecode;import org.omg.Messaging.SYNC_WITH_TRANSPORT;import java.util.Arrays;/** * * Vernam密码:Vernam密码属于流密码,其加密过程是明文与密钥按位异或,解密过程是密文与密钥按位异或。 * @author generalandroid * **/public class VernamTest {    private String key;    private String pContent;    private String cContent;    private char[] c_key;    private char[] c_content;    private char[] p_content;    public VernamTest(String key,String content){        this.key=key;        this.pContent=content;        System.out.println("密钥:"+key);        System.out.println("原文:"+pContent);        initKey();        c_key=this.key.toCharArray();        c_content=new char[pContent.length()];        p_content=pContent.toCharArray();    }    public  static void main(String[] args){        VernamTest vernamTest=new VernamTest("GEEK","GENERALANDROID");        vernamTest.encrypt();        vernamTest.decrypt();    }    /**重新构建密钥词**/    private void initKey(){        key=key+pContent.substring(0,pContent.length()-key.length());        System.out.println("转换之后的key:"+key);    }    public void encrypt(){        for(int i=0;i

置换技术

前面几种简单的加密技术都是使用的代替技术,即将明文的内容代替为其他内容 ,这里面会出现明文中没有的元素,而置换技术强调的是对明文的重排列,故不会出现明文中没有的元素。 栅栏技术:最简单的置换技术例子是栅栏技术,按照对角线的顺序写出明文, 而按行的顺序读出作为密文。举个例子:GENERALANDROID写成如下 GNRLNRI EEAADOD 则密文就为:GNRLNRIEEAADOD 一个更复杂的置换技术的例子:把消息一行一行地写成矩形块,然后按列读 出 ,但是把列的次序打乱。列的次序就是算法的密钥。 为了安全,一般对明文进行多次置换来保护信息。

要说的内容就这么多,如果文中有不对的地方,麻烦指出,如果喜欢我的文章,可以动动手指关注一下,赞一下,我会有更大的动力写出更多的文章,转载请注明出处:http://blog.csdn.net/android_jiangjun/article/details/79131386

参考资料

《密码编码学与网络安全》第六版

你可能感兴趣的文章
win10中遇到qq视频时摄像头打不开没反应的解决方法
查看>>
介绍自己的一个Android插桩热修复框架项目QuickPatch
查看>>
关于textarea的ie9的maxlength不起作用的问题,请参考如下URL解决。
查看>>
Solr Facet 查询
查看>>
C++类的继承一
查看>>
数据库分库分表(sharding)系列(五) 一种支持自由规划无须数据迁移和修改路由代码的Sharding扩容方案...
查看>>
巧用VMware Workstation的clone来制作虚拟机模板
查看>>
Spring-Mybatis MapperScannerConfigurer 取不到PropertyPlaceholderConfigurer里的值
查看>>
HP DL380G4服务器前面板指示灯的含义
查看>>
数据结构_树结构
查看>>
常用URL地址
查看>>
每天一个linux命令(19):find 命令概览
查看>>
MySQL kill操作
查看>>
windows下看端口占用
查看>>
Decommissioning a Domain Controller 降域控
查看>>
Character中的奇葩
查看>>
c++书籍推荐
查看>>
轻松监听Azure service health 状态
查看>>
获取SQL SERVER某个数据库中所有存储过程的参数
查看>>
在Linux下编译安装Apache2(2)
查看>>