精华内容
下载资源
问答
  • 对称加密算法(Symmetric-key algorithm)和非对称加密算法(asymmetric key encryption algorithm)只不过就是密码学(encryption)中的两种解密算法罢了,什么是算法,你就可以理解成为是一种规则吧,这种规则可以将信息...

    对称加密算法(Symmetric-key algorithm)和非对称加密算法(asymmetric key encryption algorithm)只不过就是密码学(encryption)中的两种解密算法罢了,什么是算法,你就可以理解成为是一种规则吧,这种规则可以将信息从一种形式转变成另一种形式,不懂没关系,继续往下看。

    对称加密

    首先,让我们先从一个情景开始讲起,想当初我们在初中,高中,甚至于大学,每次考试都有人在试图如何更加隐蔽的作弊!那大家都想了什么方法呢?比如张三学习比李四好,李四就想在考试的时候让张三“帮助”一下自己,当然,他们俩不可能像我们平常对话一样说,第一题选A,第二题选B等等,为什么?因为监考老师明白他俩在谈论什么,也就是说这种沟通交流方式属于“明文”,所以李四就想:“我需要发明一种,只有我和张三明白的交流方式”,那李四做了什么呢?恩,李四去找张三说:“当我连续咳嗽三声的时候你看我,然后如果我摸了下左耳朵,说明你可以开始给我传答案了,如果没反应,那说明我真的是在咳嗽。。。。”, 然后,怎么传答案呢?很简单,“你摸左耳朵代表A, 摸右耳朵代表B,左手放下代表C,右手放下代表D”,好了,这就是他们的“算法(规则)”,将信息的一种形式(A,B,C,D),这里我们称为“明文”,转换成了另一种形式(摸左耳朵,摸右耳朵,放左手,放右手),这里称为“密文”,经过这种转换,很显然监考老师不会明白这些“密文”,这样,张三和李四就通过“密文”的形式实现了信息的交换。

    其实,密码学不就是为了人们更好的加密传输么?有很多学者,科学家成年累月的工作,为的就是改进或者发明更好的加密算法,让这些加密算法加密的文本难以破解,达到数据安全传输的目的。

    OK,回归正题,上面这个“作弊”的例子,其实就是一种对称加密算法!好了,我们来看一下对称加密算法的定义(来源:wikipedia):

    对称密钥加密(英语:Symmetric-key algorithm)又称为对称加密、私钥加密、共享密钥加密,是密码学中的一类加密算法。这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥。实务上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通讯联系。与公开密钥加密相比,要求双方取得相同的密钥是对称密钥加密的主要缺点之一

    这里我想说一点的是,wikipedia的把Symmetric-key algorithm中文翻译是 对称密钥加密,我不想把这个key翻译成密钥,因为key仅仅是一个“钥”,这里翻译成密钥会让大家对后面所说的“公钥”,“密钥”,“私钥”等等的概念弄混,好了,所以我还是比较喜欢称之为“对称加密算法”,而后面说又称“私钥”加密,共享“密钥”,这里,“私钥”就等于“密钥”,没有任何区别,英文是“private key”。

    ok,我们将定义结合我们前面的例子对应一下,“这类算法在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥”,其实在我们例子中,密钥就是“将(A,B,C,D)转换成(摸左耳朵,摸右耳朵,放左手,放右手)”这么一个规则。“实务上,这组密钥成为在两个或多个成员间的共同秘密,以便维持专属的通讯联系。” 这句话很好理解了吧,密钥是张三和李四间共同的秘密!只有他俩事先知道。

    所以,为什么叫对称加密呢,你可以这么理解,一方通过密钥将信息加密后,把密文传给另一方,另一方通过这个相同的密钥将密文解密,转换成可以理解的明文。他们之间的关系如下:

    明文 <-> 密钥 <-> 密文

    这样看,是不是感觉对称比较好理解了。ok,那么我们现在有哪些现成的对称加密算法可以用么?当然有:

    常见的对称加密算法有DES、3DES、AES、Blowfish、IDEA、RC5、RC6。

    想深入了解的同学,可以自行查阅资料了。

    非对称加密

    我们再来说说非对称加密,非对称加密是一种比对称加密更加优秀的加密算法,当然算法有利有弊,对称加密速度快但是安全性相对于非对称加密来说低,为什么呢,你想啊,要想使用对称加密,那么分享信息的各个个体之间都需要分享这个密钥,比如你们1000个人之间都使用同一个密钥进行密文传输,只要其中一个人密钥被盗窃了,那么整体加密的信息将都被破解了。好了,那么我们开始说说非对称加密。

    就从上面提到的这个对称加密的缺点开始,怎么做到即时一个人的密钥被盗窃了,最起码保证你给其他人发送密文不被破解。于是,人们就想出了这么个办法,首先,我们停止分享共同的密钥,因为上面的bug就是来源于共享一个密钥,那么怎么办呢?每个人生成一个“私钥-公钥”对,这个私钥需要每个人自行进行保护!公钥可以随便分享,后面详细说,同时,生成的这个“私钥-公钥”对还有个强大的功能就是,使用私钥加密的信息,只能由该私钥对应的公钥才能解密,使用公钥加密的信息,只能由该公钥对应的私钥才能解密!

    好了,比如说张三生成了他自己的一个“私钥-公钥”对,叫做“张三私钥-张三公钥”,李四生成了他自己的一个“私钥-公钥”对,叫做“李四私钥-李四公钥”,之前我们说过私钥要每个个体自己进行保存,公钥可以随便分享,目的是为什么呢?是为了加密信息!

    比如,李四想给张三发送密文。
    于是李四开始给张三发QQ

    李四:
    “hi哥们,我想给你发个密文,把你的公钥给我发过来用用。”
    
    张三:
    “没问题的,这是我的公钥: d#8yHE8eU#hb*!neb,用这个公钥加密你的信息后给我发过来吧”
    
    李四:
    “这是我想对你说的话: *&#@uehuu(**#eehu&$##bfeu&&”

    恩?你是不是有点疑问呢?咳咳,李四这是作死的节奏?为什么公开问公钥?不怕被网警查水表?哈哈,非对称解密算法的威力就在这里!无所谓!随便谁截取!我们上面说了,公钥可以随意分发,所以即使别人截取了,也只是知道该公钥而已,但是要是想解密使用该公钥加密的密文!只有一个人可以办得到!就是张三! 为什么?李四使用张三的公钥加密的信息,只有张三的公钥所对应的私钥,这里就是“张三私钥”,该私钥才可以解密!所以,没有张三私钥的第三方即时截取了这些密文,也破解不了!或者更严格的说在有限时间内比如说几千年内是暴力破解不出的!

    懂了吧?所以网警们哭了,本以为想监视他们的对话,可惜一无所获!

    我们来看看非对称加密的官方定义:

    公开密钥加密(英语:public-key cryptography,又译为公开密钥加密),也称为非对称加密(asymmetric cryptography),一种密码学算法类型,在这种密码学方法中,需要一对密钥(其实这里密钥说法不好,就是“钥”),一个是私人密钥,另一个则是公开密钥。这两个密钥是数学相关,用某用户密钥加密后所得的信息,只能用该用户的解密密钥才能解密。如果知道了其中一个,并不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个的秘密性质。称公开的密钥为公钥;不公开的密钥为私钥。

    hmm。。这个定义有点绕,不过就是说,要想使用非对称加密算法,首先要有一对key,一个被称为private key私钥,一个成为public key公钥,然后可以把你的public key分发给想给你传密文的用户,然后用户使用该public key加密过得密文,只有使用你的private key才能解密,也就是说,只要你自己保存好你的private key,就能确保,别人想给你发的密文不被破解,所以你不用担心别人的密钥被盗,没关系。

    正因为,这种加密是单向的,所以被称为非对称加密算法。

    这种加密算法应用非常广泛,SSH, HTTPS, TLS,电子证书,电子签名,电子身份证等等。

    这篇文章先写到这里,接下来我将像大家挨个介绍这些加密算法的应用,不过我在这里先埋个伏笔,上面我提到的李四和张三发qq,即时使用非对称加密算法,大家有没有发现仍然有哪些隐患呢?

    给点提示,比如说,某个网警想知道到底李四要给张三发什么信息?网警想破解李四的密文,那么网警有什么办法可以获得李四要发的信息呢?很显然获得密文直接暴力破解是不可能的!

    小提示,网警可以冒充张三!!!!发送给李四“网警的公钥”,而不是“张三的公钥”,那么当李四收到该公钥的时候,就不假思索的使用该公钥加密了他的信息,然后毫不犹豫的将加密的密文发了过去,然后网警得意的笑了。

    所以,问题在哪呢?这就是数字签名和数字证书的来历!我们下回接着白话。


    读完本文章,你可以继续看如下文章:

    1. 白话解释 OSI模型,TLS/SSL 及 HTTPS(属于非对称加密算法的实际应用)

    上回我们白话了密码学中的两种算法,对称加密算法和非对称加密算法,我们有了这两种算法,我们就要将他们应用到实际生活中,就像我们学会了99乘法表,就可以让我们在实际生活中快速的计算啦!

    所以本节课程的先决条件就是,看并掌握我之前白话的这篇文章:对称加密算法vs非对称加密算法

    我们先从互联网开始说起,说到互联网我们就不得不提一下计算机,因为计算机是互联网组成的一个很重要的部分,我们要想使用互联网进行交流就必须使用计算机(注意!我这里的“计算机”是一个统称,爱钻牛角尖的童鞋,不要说,除了计算机还有手机啊,ipad啊,智能手表啊!!!!恩,好了,别闹了)。

    然后问题来了,要想形成互联网,计算机和计算机之间就必须相连起来(废话!),于是我们就有了“网线”,当然这里的“网线”也是泛指,因为现在大家家里都用的是无线网!不过无论有线网还是无线网,他们都是通过“物理”途径进行传播信号的!有了这些“联系”,我们计算机和计算机之间有了传递信息的“途径”了,但是!这里仅仅是提供了一个途径,但是如果想让计算机之间彼此了解传输的信息,那么我们必须定义一系列的协议,这些协议是计算机之间都能够明白的,同时发送和接受要严格按照协议去做!就像张三是中国人和王石头是印度人,他们俩要想交流,就要先建立一个途径,无论是加qq还是发邮件,同时他们俩还得说一样的话,不能张三说中国话,王石头说印度话。

    所以,这就是好多互联网协议的来历,比如IPv4, IPv6, TCP,UDP,HTTP,FTP,SMTP,TLS/SSL,HTTPS等等。

    那么我们再来想一下,比如,张三想通过QQ发送给李四一句“踢球去不?”,那么谁来将我们发出去的信息转换成协议规定的形式呢?QQ这个软件?操作系统?网卡?路由器?网线?还是我们的ISP(网络服务提供商,你可以理解成电信,移动,网通等等)。

    其实,这些都会涉及到,所以即使你简简单单的发送一句“踢球去不?”需要涉及到这么多内容,所以,这里要引入一个模型,叫做OSI模型,全称“开放式系统互联通信参考模型”(英语:Open System Interconnection Reference Model)。

    这个模型是干嘛的呢?就是将计算机和计算机之间信息交换“概念化”成不同的层次,每层分别有它自己的“实现”,每层有它自己的任务,同时“向上”提供“抽象”的“接口”供上层使用。一般分成7层或者5层。为了简便期间我这里按照5层架构说一下,这五层分别是:

    • 应用层(application layer)

    • 传输层(transport layer)

    • 网络层(network layer)

    • 数据链路层(data link layer)

    • 物理层(physical layer)

    回到我们的例子,当张三用QQ向李四发送一条信息时,首先QQ属于应用层,应用层需要将信息发送给传输层,传输层经过处理之后传给网络层,以此类推传给物理层,这样一层层向下“包装”,每层有对应的协议,这样最后通过物理层传出去,传到李四的物理层,然后李四那边通过一层层向上按照协议“解包”,最后到应用层,传到李四的qq里。

    所以每层都有相对应的协议比如我们的物理层和数据链路层通过无线网传输使用的802.2传输协议,有线网的Ethernet(以太网)传输协议,还有网络层的IPv4, IPv6协议,传输层的TCP, UDP协议,而我们熟悉的HTTP协议其实属于应用层,所以HTTP是建立在TCP/IPv4或v6/以太网基础上进一步细化用于传输“超文本”信息的协议,比如FTP也属于应用层,也是在下面各层协议基础上进行细化,专门用于“文件传输”的协议。

    大家可以看到,协议越往上越具体,越往下约抽象,其实计算机技术的发展就是一层层的向上抽象,这样上层的可以直接使用下层的“成果”(API)!

    我们再来说一下TLS/SSL,SSL(secure sockets layer)是TLS(transport layer security)的前身,为什么将他们合起来的,大家可以理解成都属于同一东西的不同阶段吧,比如该协议之前叫SSL后来改名成TLS了。

    为什么要有这种协议呢?因为HTTP是使用明文传输,随着网络的发展,安全性越来越重要,所以大家就要想办法让传输更加安全,同时使用密码学的成果,利用“非对称加密算法”的思想以及OSI模型,来对HTTP的信息进行加密。

    因为上面我们说了,根据OSI模型,如果向外传输信息就是要从上到下挨个层进行,TLS/SSL也是位于应用层,所以为了加密HTTP的内容,那么TLS/SSL必须位于HTTP下面,可以看成这样:

    HTTP
    TLS/SSL
    TCP
    Ip
    ..

    信息从HTTP经过TLS/SSL非对称加密后传出去,而在接收方,接收到信息是需要一层层向上进行,经过每层的“解包/解密”,最终通过HTTP转换成超文本信息。

    所以HTTPS 就是 “HTTP内容向下传输的时候加了一层TLS/SSL加密”,仅此而已,这样,我们就可以实现,使用HTTP协议进行互联网信息传播的时候,对信息进行加密处理了,相信大家已经对非对称加密算法有一定了解了。比如说我们通过HTTPS连接某银行网站,这样我们就可以将我们的密码通过银行给我们的公钥进行加密后发送给银行,而避免了在传输过程中被他人偷看的可能,因为即使他们讲我们的密文盗走,也无法解密,只有银行网站可以解密,为什么?因为只有银行拥有与我们使用“公钥”加密相对的那个“私钥”。

    但是同样的问题,就是我们怎么知道我们使用的公钥就是银行给我们的呢?即使我们所访问的域名和银行的域名一致,因为黑客完全可以通过修改我们本地的hosts文件,或者入侵dns,将域名映射到黑客的服务器。

    所以,这就是CA(certificate authority),数字证书,数字签名,公钥基础设施(PKI)等等名词的来历。



    展开全文
  • 对称加密算法

    2018-11-24 11:43:49
    对称加密算法对称加密算法的主要差别在于非对称加密算法用于加密和解密的密匙不同,一个公开称为公钥,一个保密称为私钥;这个算法解决了对称加密的算法的密匙分配的问题,提高了算法的安全性。 常见的非对称...

    非对称加密算法和对称加密算法的主要差别在于非对称加密算法用于加密和解密的密匙不同,一个公开称为公钥,一个保密称为私钥;这个算法解决了对称加密的算法的密匙分配的问题,提高了算法的安全性。

    常见的非对称加密算法:RSA算法

    1.RSA消息传递模型

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    2 RSA算法实现

    在这里插入图片描述

    3.使用Java提供的API实现

      如下测试了用私钥加密,公钥解密的过程。反之也可以测试。

    import javax.crypto.Cipher;
    import java.security.*;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    
    public class RSATest {
    
        private static final String KEY_ALGORITHM="RSA";
        private static final String PUBLIC_KEY="RSAPublicKey";
        private static final String PRIVATE_KEY="RSAPrivateKey";
        /**
         * RSA密匙长度,默认是1024位,密匙长度必须是在64的倍数
         * 范围是512--65536之间
         *
         */
        private static final int KEY_SIZE = 512;
    
        public static void main(String[] args) throws Exception {
    
            String str ="hello vison";
            Map<String, Object> map = initKey();
            byte[] pulicKey = getPulicKey(map);
            byte[] privateKey = getPrivateKey(map);
    
            byte[] dataAfterEncrypt = encryptByPrivateKey(str.getBytes(), privateKey);
            System.out.println("encrypt by privateKey: " + Base64.encodeMD5Hex(new String(dataAfterEncrypt)));
            byte[] dataAfterDecrpty = decryptByPublicKey(dataAfterEncrypt, pulicKey);
            System.out.println("decrpt by publicKey :" + new String(dataAfterDecrpty));
    
        }
        /**
         * 公钥解密
         * @param data
         * @param key
         * @return
                 * @throws Exception
         */
        public static byte[] decryptByPublicKey(byte[] data,byte[] key)throws Exception{
            //获取公钥
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            //对数据解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE,publicKey);
            return cipher.doFinal(data);
        }
    
        /**
         * 公钥加密
         * @param data
         * @param key
         * @return
         * @throws Exception
         */
        public static byte[] encryptByPublicKey(byte[] data,byte[] key)throws Exception{
            //获取公钥
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
            //对数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE,publicKey);
            return cipher.doFinal(data);
        }
    
        /**
         * 私钥解密
         * @param data
         * @param key 私钥
         * @return byte[] 返回解密后的数据
         * @throws Exception
         */
        public static byte[] decryptByPrivateKey(byte[] data,byte[] key)throws Exception{
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE,privateKey);
            return cipher.doFinal(data);
    
        }
        /**
         * 私钥加密
         * @param data 待加密数据
         * @param key 私钥
         * @return byte[] 加密数据
         * @throws Exception
         */
        public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception {
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE,privateKey);
            return cipher.doFinal(data);
        }
    
    
        /**
         * 获取私钥
         * @param keyMap
         * @return
         */
        public static byte[] getPrivateKey(Map<String,Object> keyMap){
            Key key = (Key) keyMap.get(PRIVATE_KEY);
            return key.getEncoded();
        }
        /**
         * 获取公钥
         * @param keyMap
         * @return
         */
        public static byte[] getPulicKey(Map<String,Object> keyMap){
            Key key = (Key) keyMap.get(PUBLIC_KEY);
            return key.getEncoded();
    
        }
        /**
         * 初始化密匙对
         * @return Map 密钥map
         * @throws Exception
         */
        public static Map<String,Object> initKey() throws Exception {
            //实例化密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            //初始化
            keyPairGenerator.initialize(KEY_SIZE);
            //生成密匙对
            KeyPair keyPair = keyPairGenerator.genKeyPair();
            //私钥
            RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
            //公钥
            RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
            //封装密钥
            HashMap<String, Object> map = new HashMap<>();
            map.put(PUBLIC_KEY,publicKey);
            map.put(PRIVATE_KEY,privateKey);
            return map;
        }
    }
    
    
    展开全文
  • 对称加密算法

    千次阅读 2018-11-24 10:12:55
    对称加密算法有DES、DESede、AES、Blowfish,以及RC2和RC4算法,还有其他第三方提供的软件包提供的Bouncy Castle 提供的IDEA算法 这里面DES算是最经典的算法,DESede是DES算法的变种,AES算是DES算法的替代者; DES...

    对称加密算法有DES、DESede、AES、Blowfish,以及RC2和RC4算法,还有其他第三方提供的软件包提供的Bouncy Castle 提供的IDEA算法

    这里面DES算是最经典的算法,DESede是DES算法的变种,AES算是DES算法的替代者;

    DES算法

    1.基于DES算法的消息传递模型

    在这里插入图片描述

    2. DES算法实现

    Java提供的仅支持56位密匙长度,作为补充Bouncy Castle提供64位的长度支持,再吃基础上配合不同的填充方式用来显著提供系统的安全性。如下:
    在这里插入图片描述

    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;
    import java.security.Key;
    import java.security.NoSuchAlgorithmException;
    import java.util.Base64;
    
    public class DESTest {
    
        /**
         * 密匙算法
         */
        private static final String KEY_ALGORITHM = "DES";
        /**
         * 加密/解密算法  工作模式  填充方式
         */
        private static final String CIPHER_ALGORITHM ="DES/ECB/PKCS5Padding";
    
        //测试
        public static void main(String[] args) throws Exception {
            String str = "hello vison";
            byte[] key = initKey();
            byte[] encrypt = encrypt(str.getBytes(), key);
            System.out.println("encrypt data: "+ Base64.getEncoder().encode(encrypt));
            byte[] decrypt = decrypt(encrypt, key);
            System.out.println("decrypt data: "+ new String(decrypt));
        }
    
        /**
         * 解密
         * @param data 待解密数据
         * @param key 密匙
         * @return byte[] 解密数据
         * @throws Exception
         */
        public static byte[] decrypt(byte[] data ,byte[] key) throws Exception{
            Key k = toKey(key);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE,k);
            return  cipher.doFinal(data);
    
        }
    
        /**
         * 加密
         * @param data 待加密数据
         * @param key  密匙
         * @return byte[] 加密数据
         * @throws Exception
         */
        public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
            //还原密匙
            Key k = toKey(key);
            //实例化
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
            //初始化,设置为加密模式
            cipher.init(Cipher.ENCRYPT_MODE,k);
            //执行加密操作
            return cipher.doFinal(data);
        }
    
        /**
         * 转换密匙
         * @param key
         * @return
         * @throws Exception
         */
        private static Key toKey(byte[] key) throws Exception {
            //实例化DES密匙材料
            DESKeySpec desKeySpec = new DESKeySpec(key);
            //实例化密匙工厂
            SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
            //生成密匙
            SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);
            return secretKey;
        }
    
        /**
         * 生成密匙
         * Java支持56位密匙
         * Bouncy Castle支持64位密匙
         * @return
         * @throws NoSuchAlgorithmException
         */
        public static byte[] initKey() throws NoSuchAlgorithmException {
            //实例化密匙生成器
            KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
            //初始化密匙生成器,DES长度是56位
            // 也可以这样生成默认的长度 keyGenerator.init(new SecureRandom());
            keyGenerator.init(56);
            //生成密匙
            SecretKey secretKey = keyGenerator.generateKey();
            //获取密匙的二进制编码形式
            return  secretKey.getEncoded();
    
        }
    }
    

    基于口令加密–PBE

      PBE算法综合了对称加密算法和消息摘要算法的优势,形成了对称加密算法的一个特例。这个算法是一种口令由用户自己掌管,采用随机数(这里我们叫盐)杂凑多重加密等方式保证数据的安全。PED使用口令代替了密匙。常见的PED算法如:PBEWithMD5AndDES

    1.基于PBE算法的消息通信模型

    在这里插入图片描述

    2.PBE算法实现

    在这里插入图片描述

    具体的实现和上面DES类似,只是注意需要生成盐

    展开全文
  • 与典型非对称加密算法RSA算法相比,ElGamal算法则被称为常用非对称加密算法。 ElGamal既可用于加密,又可用于数字签名,是除RSA算法外最具代表性的公钥加密算法之一。 ElGamal算法就有较好的安全性,被广发应用。...

    1. 算法概述

    ElGamal算法和ECC算法基于离散对数问题建立。与典型非对称加密算法RSA算法相比,ElGamal算法则被称为常用非对称加密算法。

    ElGamal既可用于加密,又可用于数字签名,是除RSA算法外最具代表性的公钥加密算法之一。

    ElGamal算法就有较好的安全性,被广发应用。著名的美国数字签名标准(Digital Signature Standard, DSS)就是采用ElGamal签名方案的一种变形——DSA(Digital Signature Algorithm)。

    缺点:
    ElGamal的密文会成倍扩张。

    2. 模型分析

    Java6中没有提供ElGamal算法, 但是Bouncy Castle中对ElGamal算法进行了实现。ElGamal算法在构建密钥时的操作流程几乎和RSA算法完全一致。所不同的是RSA中是Alice构建密钥, 而在ElGamal中,Bob成了密钥构建方。假设的消息模型如下:
    Alice为消息发送方,Bob为消息接收方,双方在消息发送前已将ElGamal算法作为消息传递的加密算法。

    ElGamal加密算法流程图
    在这里插入图片描述

    1. 构建并发布密钥

    1、2步骤为构建密钥流程

    1. 使用密钥进行加密消息的交互

    3、4、5为使用密钥进行加密消息交互

    Bouncy Castle提供的ElGamal算法实现遵循 “公钥加密, 私钥解密”的加密/解密方式。

    3. 代码实现

    Bouncy Castle对ElGamal算法具体实现细节如下:

    算法 密钥长度 密钥默认长度 工作模式 填充模式 备注
    ElGamal 160~16384位(密钥长度为8的整数倍) 1024 ECB、NONE NoPadding、PKCS1Padding、OAEPWithMD5AndMGF1Padding、OAEPWithSHA1AndMGF1Padding、OAEPWithSHA224AndMGF1Padding、OAEPWithSHA256AndMGF1Padding、OAEPWithSHA384AndMGF1Padding、OAEPWithSHA512AndMGF1Padding、ISO9796-1Padding Bouncy Castle实现

    3.1 算法实现

    package com.calvin.android.demo2.secrity;
    
    import android.util.Log;
    
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    
    import java.security.AlgorithmParameterGenerator;
    import java.security.AlgorithmParameters;
    import java.security.Key;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.Provider;
    import java.security.PublicKey;
    import java.security.SecureRandom;
    import java.security.Security;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.DHParameterSpec;
    
    /**
     * Author:cl
     * Email:lhzheng@grandstream.cn
     * Date:20-10-20
     */
    public class ElGamalCoder {
        //非对称加密密钥算法
        public static final String KEY_ALGORITHM = "ElGamal";
    
        private static final int KEY_SIZE = 256;
        private static final String PUBLIC_KEY = "ElGamalPublicKey";
        private static final String PRIVATE_KEY = "ElGamalPrivateKey";
    
        /**
         * 私钥解密
         * @param data 待解密数据
         * @param key 私钥
         * @return byte[] 解密数据
         * @throws Exception 异常
         */
        public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
    
            //取得私钥
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM );
            //生成私钥
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
            //对数据解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return cipher.doFinal(data);
        }
    
        /**
         * 私钥加密
         * @param data 待加密数据
         * @param key 私钥
         * @return byte[] 加密数据
         * @throws Exception 异常
         */
        public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
    
            //取得私钥
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            //生成私钥
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
            //对数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            return cipher.doFinal(data);
        }
    
        /**
         * 公钥解密
         * @param data 待解密数据
         * @param key 公钥
         * @return byte[] 解密数据
         * @throws Exception 异常
         */
        public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {
            //取得公钥
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            //生成公钥
            PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
            //对数据解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            return cipher.doFinal(data);
        }
    
        /**
         * 公钥加密
         * @param data 待加密数据
         * @param key 公钥
         * @return byte[] 加密数据
         * @throws Exception 异常
         */
        public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
            //取得公钥
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            //生成公钥
            PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
            //对数据解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return cipher.doFinal(data);
        }
    
        private static final String TAG = "ElGamalCoder";
    
        public static Map<String, Object> initKey() throws Exception {
    
            //实例化BC Provider, Android系统支持BC Provider, 这里将系统可能是旧的版本去掉,加入新版本的BC Provider
            Provider bcProvider = new BouncyCastleProvider();
            Security.removeProvider("BC");
            Security.addProvider(bcProvider);
    
    		/**
            Provider[] providers = Security.getProviders();
            for (Provider provider: providers){
                Log.d(TAG, "provider name = "+provider);
    
                for (Map.Entry<Object, Object> entry: provider.entrySet()){
                    Log.d(TAG, "\t "+entry.getKey()+", "+entry.getValue());
                }
            }
    		**/
    
            AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance(KEY_ALGORITHM, bcProvider);
            //初始化算法参数生成器
            apg.init(KEY_SIZE);
            //生成算法参数
            AlgorithmParameters algorithmParameters = apg.generateParameters();
            //构建参数材料
            DHParameterSpec elParams = (DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class);
            //实例化密钥对生成器
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            //初始化密钥对生辰其
            keyPairGen.initialize(elParams,new SecureRandom());
            //生成密钥对
            KeyPair keyPair = keyPairGen.generateKeyPair();
            //公钥
            PublicKey publicKey = keyPair.getPublic();
            //私钥
            PrivateKey privateKey = keyPair.getPrivate();
            //封装密钥
            Map<String, Object> keyMap = new HashMap<>(2);
            keyMap.put(PUBLIC_KEY, publicKey);
            keyMap.put(PRIVATE_KEY, privateKey);
            return keyMap;
        }
    
        public static byte[] getPublicKey(Map<String, Object> keyMap){
    
            return  ((Key)keyMap.get(PUBLIC_KEY)).getEncoded();
        }
    
        public static byte[] getPrivateKey(Map<String, Object> keyMap){
            return  ((Key)keyMap.get(PRIVATE_KEY)).getEncoded();
    
        }
    }
    
    

    3.2 测试代码

    @Test
        public void testElGamal() throws Exception {
            Map<String, Object> keyMap = ElGamalCoder.initKey();
            //公钥
             byte[] elgamalPubKey = ElGamalCoder.getPublicKey(keyMap);
            //私钥
             byte[] elgamalpriKey = ElGamalCoder.getPrivateKey(keyMap);
    
            System.out.println("公钥:\t"+ Base64.encodeToString(elgamalPubKey, Base64.DEFAULT));
            System.out.println("私钥:\t"+ Base64.encodeToString(elgamalpriKey, Base64.DEFAULT));
            String inputStr = "ElGamal加密";
            byte[] data = inputStr.getBytes();
            System.out.println("原文:\t"+ inputStr);
            byte[] encodedData = ElGamalCoder.encryptByPublicKey(data, elgamalPubKey);
            System.out.println("加密后:\t"+ Base64.encodeToString(encodedData,Base64.DEFAULT));
            byte[] decodedData = ElGamalCoder.decryptByPrivateKey(encodedData, elgamalpriKey);
            String outputStr = new String(decodedData);
            System.out.println("解密后:\t"+ outputStr);
            assertEquals(inputStr,outputStr);
    
        }
    

    3.3 运行结果

    2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: 公钥:	MHcwUAYGKw4HAgEBMEYCIQD/GaVs/HmUpVVOtSF8C0t/OcPNEHO83sjCdvdhkBM5fwIhAKkFaKSP
    2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: nrJIz2duJFVY+kEstf31SVuOlLmyt93MghofAyMAAiAKp+k1o2R5ZlBcUvOGwVPl4xtbNjNM6yHi
    2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: 4lD2+/1Omw==
    2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: 私钥:	MHoCAQAwUAYGKw4HAgEBMEYCIQD/GaVs/HmUpVVOtSF8C0t/OcPNEHO83sjCdvdhkBM5fwIhAKkF
    2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: aKSPnrJIz2duJFVY+kEstf31SVuOlLmyt93MghofBCMCIQDQXbdvrqqfhkLAfMEGvsLtbawlxsg+
    2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: wydVKsyJKgZpyg==
    2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: 原文:	ElGamal加密
    2020-10-20 17:02:17.019 11052-11067/com.calvin.android.demo2 I/System.out: 加密后:	Rx58tvdX4HHKSlAFjTAxRnB0UwZL3L2IVzeQ+KlG7MuBkNRn7hAQ4KKLi/tgTmYDmDsia7VVDEbU
    2020-10-20 17:02:17.019 11052-11067/com.calvin.android.demo2 I/System.out: pLGxfKSoHw==
    2020-10-20 17:02:17.021 11052-11067/com.calvin.android.demo2 I/System.out: 解密后:	ElGamal加密
    
    展开全文
  • 对称加密算法之DES

    2020-10-19 16:46:37
    DES算法是对称加密算法领域的典型算法,为后续对称加密算法发展奠定了基础。DESede算法基于DES算法进行三重迭代,增加了算法安全性。 DES最早有IBM提出,NIST将其采纳为标准,即数据加密标准(Data Encryption ...
  • 4、RSA算法相对于DES/AES等对称加密算法,他的速度要慢的多 5、总原则:公钥加密,私钥解密 / 私钥加密,公钥解密 二、模型分析 RSA算法构建密钥对简单的很,这里我们还是以甲乙双方发送数据为模型 ...
  • 4.RSA算法相对于DES/AES等对称加密算法,他的速度要慢的多 5.总原则:公钥加密,私钥解密 / 私钥加密,公钥解密 二、模型分析 RSA算法构建密钥对简单的很,这里我们还是以甲乙双方发送数据为模型 1.甲方在本地构建...
  • 对称加密算法的加密密钥和解密密钥相同,用密钥对原数据加密得到密文,对密文解密密得到明文,解密算法是加密算法的逆运算。 DES是最具代表性的对称加密算法,DESede是DES算法的变种又称3DES。DES算法有ecb和cbc两...
  • 对称加密的加密密钥和解密解密密钥一致,即加密和解密用同一个密钥。...RSA是常用的非对称加密算法。   RSA算法 模型如下 算法实现 /** * 初始化RSA密钥对 * @return */ public static S...
  • 对称加密算法-ElGamal算法

    万次阅读 2011-04-05 16:12:00
     1、ElGamal算法和ECC算法基于离散对数问题  2、这个是一个单向的过程。虽然密钥对构造简单,但是只是乙方向另外一方单向传送数据进行加解密,不能反向操作  3、这里只有“公钥加密、私钥解密”这个过程  4、...
  •  UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。  不加密...
  • 对称加密算法之DH算法1. 算法简述2. 模型分析3. 代码实现4. 算法实现分析 1. 算法简述 对称加密算法提高数据安全性,但是带来了密钥管理的复杂性, 如何安全地传递密钥成为棘手问题。密钥交换算法(Diffie-Hellman...
  • 以下是一些个人的理解,欢迎各位一起交流和进步。...B:客户端对数据(明文)进行AES加密和MD5获取摘要信息,然后利用RSA用服务器的公玥对AES所使用的对称密钥进行加密。把所有数据整合在一起。 C:客户...
  • 计算机网络 对称加密与非对称加密

    千次阅读 2015-09-27 22:36:25
    对称加密模型如下图所示: 用户A向B发送明文X,但通过加密算法E运算后,就得到密文Y。 Y=EK(X) 图中所示的加密和解密用的密钥K是一串秘密的字符串(或比特串)。在传送过程中可能出现密文的截获...
  • 对称密码算法概述对称密码算法理解对称分组加密算法的优缺点和应用场合理解DES3DESAESIDEA的特点和历史背景了解DES3DES算法的工作原理对称分组加密通信模型Oscar加密目的Alice和Bob在不安全的信道上进行通信而破译者...
  • 对称密码算法概述.pdf

    2020-06-09 21:52:24
    对称密码算法概述 对称密码算法 理解对称分组加密算法的优缺点和应用场合 理解DES3DESAESIDEA的特点和历史背景 了解DES3DES算法的工作原理 2 对称分组加密通信模型 Oscar 加密目的 密文y Alice和Bob在 明文x 明文x ...
  • 加密算法复习

    2019-02-27 15:07:24
    学习了加密算法的数学模型后,自己对这节课的学习做一次整理. 加密算法大体上可以理解为 将明文转换为密文的过程,相反的,解密算法即为将密文解密为明文的过程. 课堂介绍了两类加密算法 分别是: 对称秘钥算法 和...
  • 对称加密体系

    2018-09-04 22:27:32
    加密算法:对明文进行各种代替和替换。 密钥:独立于明文和算法,也是加密算法的输入。算法根据所用的特定的密钥而产生不同的输出。 密文:算法的输出,依赖于明文和密钥。 解密算法:加密算法的逆运算,既得到明文...
  • 二、对称加密算法家谱1.引入库2.读入数据总结 前言 项目中经常会对数据库的密码加密后放到配置文件中,启动项目连接数据库时再对其进行解密,此加密与解密过程一般采用对称加密算法。本篇主要介绍什么是对称加密...
  • 一、概述 1、DSA是以RSA为基础形成的 2、java6提供了DSA的实现,但是java6只提供了SHA1withDSA的实现 ...这个和RSA一样,只是换了一个算法而已   三、代码分析   package com.ca.test;  import java.se...
  • 公钥加密模型;公钥密码的重要特性;常用的公钥密码算法;RSA公钥密码体制(Left to Right: Ron Rivest, Adi Shamir, Len Adleman;RSA算法操作过程;RSA 算法加密/解密过程;RSA加密过程举例;RSA 算法的安全性和性能;椭圆...
  • JAVA RSA非对称加密

    2019-06-23 20:04:21
    4.RSA算法相对于DES/AES等对称加密算法,他的速度要慢的多 5.总原则:公钥加密,私钥解密 / 私钥加密,公钥解密 二、模型分析 RSA算法构建密钥对简单的很,这里我们还是以甲乙双方发送数据为模型 1.甲方在本地构建...
  • 文章目录TLS 协议-对称加密原理1.TLS 设计的目的2.TLS/SSL 发展历史及通用模型3.TLS 协议4.TLS 安全密码套件解读5.对称加密示意图6.基于 XOR 的对称加密原理6.1 XOR 真值表6.2 基于 XOR 的加密示意图6.3 基于 XOR 的...
  • Java-对称加密-AES

    千次阅读 2016-06-11 19:56:53
    对称加密算法中常用的算法有:DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK、AES等。 对称算法AES Base64Decoder package com.ding.test; import java.io....
  • 对称加密算法取决于密钥的保密性,算法是公开的(所有人都可以检测算法的好坏) 模型:加密:C = EK(P) 解密:P = DK(C) feistel密码结构 是很多对称加密算法的结构(如DES) 输入为长度为2w的明文分组及密钥k,进行...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 209
精华内容 83
关键字:

对称加密算法模型