精华内容
下载资源
问答
  • 哈希算法用途
    千次阅读
    2019-05-25 21:35:44

    什么是哈希算法

    一说到哈希算法, 我瞬间就想到了哈希函数、哈希表, 其实他们并不是一回事.

    简单来说, 哈希算法就是将任意长度的字符串通过计算转换为固定长度的字符串, 不对, 不光字符串, 应该说是将任意长度的二进制串转换为固定长度的二进制串, 这个转换的过程就是哈希算法.

    既然将任意长度的字符串转换成固定长度的, 那么冲突就不可避免了, 比如将0-100所有的数字, 映射到0-10这十个数字上, 难免会发生冲突. 一般来说, 计算得出的哈希值越长, 冲突的概率就越低, 比如说, 计算过后, 哈希值为16个字节, 也就是128位, 那么就有2^128个不同的哈希值, 发生哈希冲突的概率为(1/2)^128, 这个概率可以说很低了.

    以MD5为例, 以下是经过MD5转换后的值:

    朋友你好: 677fe16950241e74ef632efb2b9f92a7

    朋友你好!: 6efa551df87d9de987f17be4e73eb720

    可以看到, 哪怕仅仅差了一个感叹号, 计算后的值也是天壤之别, 所以很多网站上下载文件的同时还提供md5值, 现在能够理解了吧, 你将下载后的文件通过md5算法进行计算, 得到的字符串如果和网站给定的不相同, 说明文件被修改过了.

    当然, 哈希算法不仅仅只有md5这一种, 以用途来分析哈希算法, 就不说哈希算法的原理了, 因为我不会.

    1. 数据校验

    上面说到的md5就是其中的一个, 好像还有一个什么SHA, 不过我不知道, 也就不展开探讨了.

    md5可以将一个文件经过计算转换成一个指定长度的字符串, 可以防止文件被篡改, 但是通过加密后的字符串很难逆向推出原文.

    前面那个例子可以看到, 即使文件被修改了一点点, 也会导致计算后的值发生很大变换.

    2.唯一标识

    比如说, 现在有十万个文件, 给你一个文件, 要你在这十万个文件中查找是否存在. 一个很笨的办法就是把每一文件都拿出来, 然后按照二进制串一一进行对比. 但是这个操作注定是比较费时的.

    可以用哈希算法对文件进行计算, 然后比较哈希值是否相同. 因为存在哈希冲突的情况, 你可以在相同哈希值的文件再进行二进制串比较.

    3.哈希表

    在哈希表中使用哈希函数已经并不陌生了, 不再赘述.

    4.负载均衡

    比如说, 现在又多台服务器, 来了一个请求, 如何确定这个请求应该路由到哪个路由器呢?当然, 必须确保相同的请求经过路由到达同一个服务器. 一种办法就是保存一张路由关系的表, 比如客户端IP和服务器编号的映射, 但是如果客户端很多, 势必查找的时间会很长. 这时, 可以将客户端的唯一标识信息(如:IP、username等)进行哈希计算, 然后与服务器个数取模, 得到的就是服务器的编号.

    5.分布式存储

    当我们有大量数据时, 一般会选择将数据存储到多个服务器, 为了提高读取与写入的速度嘛. 决定将文件存储到哪台服务器, 就可以通过哈希算法取模的操作来得到.

    但是, 如果数据多了, 要增加服务器了, 问题就来了, 比如原来是10台服务器, 现在变成15台了, 那么原来哈希值为16的文件被分配到编号6的服务器, 现在被分配到编号1的服务器, 也就意味着所有文件都要重新计算哈希值并重新非陪服务器进行存储. 一致性哈希就是这个用途, 可以查找我的历史文章.

    暂时我能想到的就只有这些, 当然, 哈希算法的用途还有很多, git中的commit id等, 但是我不太了解, 就假装没有吧, 嘿嘿


    有时对用户的密码进行MD5加密再保存, 确实要比明文保存好的多. 但是, 你以为通过哈希算法进行加密就万事大吉了么? 不好意思, 并不能, 像前面提到的MD5就已经号称别破解了.

    比如, 你将用户的密码进行MD5加密后进行保存, 若有心人拿到你的数据库数据, 虽然得到的是加密后的密码, 但是只要准备一个常用密码的字典, 将字典中的密码进行加密后与数据库保存的数据进行比较, 如果相同, 基本上就可以确定了.

    我感觉可以对密码进行双层加密, 也就是使用两个不同的加密算法, 一个算法的输出作为另一个的输入, 增大一些破解的难度吧.

    再见!!!

    更多相关内容
  • 哈希算法的原理和用途详解

    千次阅读 2021-04-20 13:27:53
    什么是哈希算法?哈希是一种加密算法,也称为散列函数或杂凑函数。哈希函数是一个公开函数,可以将任意长度的消息M映射成为一个长度较短且长度固定的值H(M),称H(M)为哈希值、散列值(Hash Value)、杂凑值或者...

    什么是哈希算法?哈希是一种加密算法,也称为散列函数或杂凑函数。哈希函数是一个公开函数,可以将任意长度的消息M映射成为一个长度较短且长度固定的值H(M),称H(M)为哈希值、散列值(Hash Value)、杂凑值或者消息摘要。它是一种单向密码体制,即一个从明文到密文的不可逆映射,只有加密过程,没有解密过程。

    Hash的特点

    易压缩:对于任意大小的输入x,Hash值的长度很小,在实际应用中,函数H产生的Hash值其长度是固定的。

    易计算:对于任意给定的消息,计算其Hash值比较容易。

    单向性:对于给定的Hash值,要找到使得在计算上是不可行的,即求Hash的逆很困难。在给定某个哈希函数H和哈希值H(M)的情况下,得出M在计算上是不可行的。即从哈希输出无法倒推输入的原始数值。这是哈希函数安全性的基础。

    抗碰撞性:理想的Hash函数是无碰撞的,但在实际算法的设计中很难做到这一点。

    有两种抗碰撞性:一种是弱抗碰撞性,即对于给定的消息,要发现另一个消息,满足在计算上是不可行的;另一种是强抗碰撞性,即对于任意一对不同的消息,使得在计算上也是不可行的。

    高灵敏性:这是从比特位角度出发的,指的是1比特位的输入变化会造成1/2的比特位发生变化。消息M的任何改变都会导致哈希值H(M)发生改变。即如果输入有微小不同,哈希运算后的输出一定不同。

    哈希算法有什么用途?

    哈希算法可以检验信息是否是相同的,这样的优势可以节省重复文件传送的时间。

    举一个生活中很平常的例子,我们在生活工作中会使用一些软件给别人传送文件数据,如果有人传送了一份文件给一个人,然后又有一个人传送了相同的文件给了另外一个人,那么这个社交软件在第二次传送文件的时候会对比两次传送的哈希值,发现是相同的,该软件就不会再次上传文件给服务器了。

    除此之外,哈希算法还可以检验信息的拥有者是否真实。

    比如,我们在一个网站注册一个账号,如果网站把密码保存起来,那这个网站不论有多安全,也会有被盗取的风险。但是如果用保存密码的哈希值代替保存密码,就没有这个风险了,因为哈希值加密过程是不不可逆的。

    哈希算法会不会被破解?

    从理论上说,哈希值是可以被获得的,但是对应的用户密码很难获得。

    假设一个网站被攻破,黑客获得了哈希值,但仅仅只有哈希值还不能登录网站,他还必须算出相应的账号密码。

    计算密码的工作量是非常庞大且繁琐的,严格来讲,密码是有可能被破译的,但破译成本太大,被成功破译的几率很小,所以基本是不用担心密码泄露的。

    当然,黑客们还可以采用一种物理方法,那就是猜密码。他可以随机一个一个的试密码,如果猜的密码算出的哈希值正好与真正的密码哈希值相同,那么就说明这个密码猜对了。

    密码的长度越长,密码越复杂,就越难以猜正确。如果有一种方法能够提高猜中密码的可能,那么可以算是哈希算法被破解了。

    比如说,例如原本猜中的概率是1/10000000000000,现在增加到了1/1000。如果每猜一个密码需要1秒,按照之前的概率猜,直到地球毁灭都可能没猜中,但后者只需要1小时就足够了。在这样的情况下,哈希算法就算是被破解啦。

    以上,是为大家分享"哈希算法的原理和用途详解”的全部内容,如果用户遇到的问题不能解决,可通过wosign官网客服寻求帮助,凡是选择wosign ssl证书的网站用户,wosign可提供免费一对一的ssl证书技术部署支持,免除后顾之忧.

    展开全文
  • 常见哈希算法总结

    多人点赞 2022-07-21 19:02:33
    哈希算法又称摘要算法,它的作用是对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希算法的目的为了验证原始数据是否被篡改。哈希算法的特点就是1.相同的输入一定得到相同的输出;2.不同的输入大概率...

    目录

    哈希算法概述

    常见的哈希算法:

    MD5算法

     SHA-1算法:

     哈希算法的用途

    校验下载文件

    存储用户密码

    Hmac MD5算法


    哈希算法概述

    哈希算法又称摘要算法,它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希算法的目的:为了验证原始数据是否被篡改。

    哈希算法的特点就是:

    1.相同的输入一定得到相同的输出;

    2.不同的输入大概率得到不同的输出。

    常见的哈希算法:

    算法输出长度(位)输出长度(字节)
    MD5128bit16bytes
    SHA-1160bit20bytes
    RipeMD-160160bit20bytes
    SHA-256256bit32bytes
    SHA-512512bit64bytes

    Java标准库提供了常用的哈希算法,并且有一套统一的接口。以MD5算法为例,看看如何对输入计算哈希:

    MD5算法

    	public static void main(String[] args) throws IOException {
    
    		try {			
               //获取一个MessageDigest对象:
    			MessageDigest digest = MessageDigest.getInstance("MD5");
    			//把要加密的内容转换成字节数据
    			byte[] simpledata = "hnczjtyrbl".getBytes();
    			System.out.println("原始数据:"+Arrays.toString(simpledata));
    			digest.update(simpledata);
    			//获得加密后的数据:
    			byte[] result = digest.digest();
    			System.out.println("加密后的数据:"+Arrays.toString(result));
    			//转换成十六进制的字符串
    			StringBuilder sb = new StringBuilder();
    			for(byte b:result) {
    				sb.append(String.format("%x", b));
    			}
    			
    			System.out.println("转换成16进制字符串:"+sb);
    			System.out.println("长度:"+sb.length());
    			} catch (NoSuchAlgorithmException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}
    

    MD5算法先获得一个MessageDigest对象,然后用update()方法传入要加密内容的字节数组。然后通过digest()方法获得最终加密的结果。

     SHA-1算法:

    SHA-1算法和MD5算法用法类似,不同的一点就是MD5加密的结果是一个长度为16的字节数组,而SHA-1加密的结果是一个长度为20的字节数组。

    public static void main(String[] args) throws IOException {
    
    		try {// 要加密的内容
    			String password = "hdljdylzsx";
    			// 创建一个MessageDigest对象:
    			MessageDigest digest1 = MessageDigest.getInstance("SHA-1");
    			// 更新要加密的数据
    			digest1.update(password.getBytes());
    			byte[] resultArray1 = digest1.digest();
    			System.out.println("原始数据:" + Arrays.toString(password.getBytes()));
    			// 加密后的结果
    			System.out.println("加密后的结果:" + Arrays.toString(resultArray1));
    			System.out.println("长度:" + resultArray1.length);
    			StringBuilder sb = new StringBuilder();
    			for (byte b : resultArray1) {
    				sb.append(String.format("%x", b));
    			}
    			System.out.println("转换成16进制字符串:" + sb);
    			System.out.println("长度:" + sb.length());
    
    		} catch (NoSuchAlgorithmException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}

     哈希算法的用途

    校验下载文件

    因为相同的输入永远会的到相同的输出,因此,如果输入被修改了,得到的输出就会不同。我们在网站上下载软件的时候,经常会看到下载页显示MD5哈希值:

    不存储用户的原始口令,那么如何对用户进行认证?方法是存储用户口令的哈希,例如,MD5。在用户输入原始口令后,系统计算用户输入的原始口令的MD5并与数据库存储的MD5对比,如果一致,说明口令正确,否则,口令错误。

    如何判断下载到本地的软件是原始的、未经篡改的文件?我们只需要自己计算一下本地文件的哈希值,再与官网公开的哈希值对比,如果相同,说明文件下载正确,否则,说明文件已被篡改。

    存储用户密码


    哈希算法的另一个重要用途是存储用户口令。如果直接将用户的原始口令存放到数据库中,会产生极大的安全风险:
    1.数据库管理员能够看到用户明文口令;
    2.数据库数据一旦泄漏,黑客即可获取用户明文口令。

    使用哈希口令时,还要注意防止彩虹表攻击。什么是彩虹表呢?上面讲到了,如果只拿到MD5,从MD5反推明文口令,只能使用暴力穷举的方法。然而黑客并不笨,暴力穷举会消耗大量的算力和时间。但是,如果有一个预先计算好的常用口令和它们的MD5的对照表,这个表就是彩虹表。如果用户使用了常用口令,黑客从MD5一下就能反查到原始口令:

    当然,我们也可以采取特殊措施来抵御彩虹表攻击:对每个口令额外添加随机数,这个方法称之为“加盐”。这样即使数据库泄露,黑客也不能获得用户明文。

    Hmac MD5算法

    public static void main(String[] args) {
    		String password = "yyzsbjr";
    		try {
    			// 生成秘钥
    			// 秘钥生成器keyGenerator
    			KeyGenerator keyGen = KeyGenerator.getInstance("HmacMD5");
    			//生成秘钥key
    			SecretKey key = keyGen.generateKey();
    			byte[] keyByteArray = key.getEncoded();
    			System.out.println("秘钥长度" + keyByteArray.length);
    			StringBuilder sb = new StringBuilder();
    			for (byte b : keyByteArray) {
    				sb.append(String.format("%02x", b));
    			}
    			System.out.println(sb);
    
    			System.out.println(sb.length());
    			Mac mac = Mac.getInstance("HmacMD5");
    			mac.init(key);
    			mac.update(password.getBytes());
    			byte[] resultByteArray = mac.doFinal();
    			System.out.println("加密结果:" + resultByteArray.length + "字节");
    			StringBuilder resultStr = new StringBuilder();
    			for (byte b : resultByteArray) {
    				resultStr.append(String.format("%02x", b));
    
    			}
    			System.out.println("加密长度" + resultStr.length());
    			System.out.println("加密内容:" + resultStr);
    		} catch (NoSuchAlgorithmException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		} catch (InvalidKeyException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    	}

    和MD5相比,使用HmacMD5的步骤是:
    1.通过名称HmacMD5获取KeyGenerator实例;
    2.通过KeyGenerator创建一个SecretKey实例;
    3.通过名称HmacMD5获取Mac实例;
    4.用SecretKey初始化Mac实例;
    5.对Mac实例反复调用update(byte[])输入数据;
    6.调用Mac实例的doFinal()获取最终的哈希值。得到加密后的结果。

     

    展开全文
  • 例如小明要加密一个文件发送给小红,他应该首先向小红索取她的公钥,然后,他用小红的公钥加密,把加密文件发送...理论上讲,哈希碰撞一定存在,因为输出的字节长度是固定的,但是输入的值是无穷的,是没有限制的。...

    哈希算法
    哈希算法又称哈希摘要算法。他一般是对一个目标,一个对象,一些字节码,摘取一部分进行计算,得到一个固定长长度的输出摘要。一般而言哈希算法的目的是未来验证原始数据是否被篡改。

    在Javaz中字符串的hashCode()就是一个哈希算法,它的输入是任意字符串,输入是固定的4字节int整数:

    "hello".hashCode(); // 0x5e918d2
    "hello, java".hashCode(); // 0x7a9d88e8
    "hello, bob".hashCode(); // 0xa0dbae2f
    

    哈希算法的特点
    相同的输入一定得到相同的输出;
    不同的输入大概率得到不同的输出;
    从这两个特点就可以看出,有可能不同的输入,得到相同的哈希值。
    我们把这种情况叫做哈希碰撞
    哈希碰撞是指:两个不同的输入得到相同的输出:
    理论上讲,哈希碰撞一定存在,因为输出的字节长度是固定的,但是输入的值是无穷的,是没有限制的。无穷对应有穷,一定会有重复。
    碰撞显然是不好的,如何降低碰撞的概率是研究哈希算法的安全性的必要性。一个安全的哈希算法必须满足:
    1碰撞概率低
    2不能被猜测输出

    根据碰撞概率,哈希算法的输出长度越长,就越难产生碰撞,也就越加安全
    常用的的哈希算法:
    在这里插入图片描述
    java的标准库中提供了常用的哈希算法,并且有一套统一的接口。以MD5为例:
    i

    
    ```java
    mport java.security.MessageDigest;
    
    public class main {
    	public static void main(String[] args)  {
    		// 创建一个MessageDigest实例:
            MessageDigest md = MessageDigest.getInstance("MD5");
           
            // 反复调用update输入数据:
            md.update("Hello".getBytes("UTF-8"));
            md.update("World".getBytes("UTF-8"));
            
            // 16 bytes: 68e109f0f40ca72a15e05cc22786f8e6
            byte[] results = md.digest(); 
    
            StringBuilder sb = new StringBuilder();
            for(byte bite : results) {
            	sb.append(String.format("%02x", bite));
            }
            
            System.out.println(sb.toString());
    	}
    }
    

    使用MeeasgeDIge时,我们首先根据哈希算法获取一个MessagDigest实例,然后反复调用update(byte[])输入数据,当输入结束后,调用digest()方法byte[]数组表示的摘要,最后,把它转换为十六进制的字符串。
    运行上述代码,可以得到HelloWorld的MD5是68e109f40c72a15e05cc22786f8e6。

    哈希算法用途

    可以用来校验下载文件和储存用户密码
    校验下载文件:
    因为相同的输入会得到相同的输出,因此,如果输入被修改了,得到的输出就会不同。只要计算一下本地文件的哈希值,再与官网公开的哈希值对比,相同,就说明文件下载正常,否则文件被篡改。

    存储用户密码:
    在数据库中存储用户口令的哈希值,只要用户输入原始口令后,系统计算用户输入的原始口令的哈希值,与保存在数据库重点哈希值相等就说明口令正确。
    使用哈希值作为口令的时候,还需要防止彩虹表攻击。彩虹表是什么呢?彩虹表就是一个已经计算好常用口令和它们的MD5的对照表,这个表就是彩虹表。如果有用户使用了常用口令,从彩虹表就可以反差到原始口令。
    我们可以采用加盐的方法来抵御彩虹表的攻击:对每个口令额外添加随机书,这个方法称之为加盐(salt)
    digest=md5(salt+inputPassword);
    SHA-1算法和MD5一样也是一种哈希算法,他输出是160bits,即是20字节。还有SHA-256 SHA-512等

    import java.security.MessageDigest;

    public class main {
    public static void main(String[] args) {
    // 创建一个MessageDigest实例:
    MessageDigest md = MessageDigest.getInstance(“SHA-1”);

        // 反复调用update输入数据:
        md.update("Hello".getBytes("UTF-8"));
        md.update("World".getBytes("UTF-8"));
        
        // 20 bytes: db8ac1c259eb89d4a131b253bacfca5f319d54f2
        byte[] results = md.digest(); 
    
        StringBuilder sb = new StringBuilder();
        for(byte bite : results) {
        	sb.append(String.format("%02x", bite));
        }
        
        System.out.println(sb.toString());
    }
    

    }

    
    对称式加密:
    
    对称加密算法就是传统的用一个密码进行加密和解密。例如,我们常用的 WinZIP 和WinRAR对压缩包的加密和解密,就是使用对称加密算法。
    
    从程序的角度看,所谓加密,就是这样一个函数,它接收密码和明文,然后输出密文:
    secret = encrypt(key,message);
    而解密则相反,它接收密码和密文,然后输出明文:
    plain = decrypt(key,secret);
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/3db48750354545ad90200562a8d6450c.png)
    密钥长度直接决定加密强度,而工作模式和填充模式可以看成是对称加密算法的参数和格式选择。Java标准库提供的算法实现并不包括所有的工作模式和所有填充模式,但是通常我们只需要挑选常用的使用就可以了。
    最后注意, DES 算法由于密钥过短,可以在短时间内被暴力破解,所以现在已经不安全了。
    、
    **用AES算法加密**
    使用AES算法的ECB模式加密并解密。
    
    ```java
    import java.security.*;
    import java.util.Base64;
    
    import javax.crypto.*;
    import javax.crypto.spec.*;
    
    public class Main {
        public static void main(String[] args) throws Exception {
          
            String message = "Hello, world!";
            System.out.println("Message(原始信息): " + message);
            
           
            byte[] key = "1234567890abcdef".getBytes();
            
         
            byte[] data = message.getBytes();
            byte[] encrypted = encrypt(key, data);
            System.out.println("Encrypted(加密内容): " + 
            					Base64.getEncoder().encodeToString(encrypted));
            
         
            byte[] decrypted = decrypt(key, encrypted);
            System.out.println("Decrypted(解密内容): " + new String(decrypted));
        }
    
    
        public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
        
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
        	
      
            SecretKey keySpec = new SecretKeySpec(key, "AES");
            
          
            cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            
           
            return cipher.doFinal(input);
        }
    
        // 解密:
        public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {
        	Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            SecretKey keySpec = new SecretKeySpec(key, "AES");
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            return cipher.doFinal(input);
        }
    }
    

    CBC模式

    cbc模式是在原来的AES加密模式的基础加入了一个IV参数,作为它的随机数,这样的情况下,对于同一份明文,每次生成的密文都不同。

    package com.apesource.demo04;
    
    import java.security.*;
    import java.util.Base64;
    
    import javax.crypto.*;
    import javax.crypto.spec.*;
    
    public class Main {
    	public static void main(String[] args) throws Exception {
            // 原文:
            String message = "Hello, world!";
            System.out.println("Message(原始信息): " + message);
            
            // 256位密钥 = 32 bytes Key:
            byte[] key = "1234567890abcdef1234567890abcdef".getBytes();
            
            // 加密:
            byte[] data = message.getBytes();
            byte[] encrypted = encrypt(key, data);
            System.out.println("Encrypted(加密内容): " + 
    				Base64.getEncoder().encodeToString(encrypted));
            
            // 解密:
            byte[] decrypted = decrypt(key, encrypted);
            System.out.println("Decrypted(解密内容): " + new String(decrypted));
        }
    
        // 加密:
        public static byte[] encrypt(byte[] key, byte[] input) throws GeneralSecurityException {
            // 设置算法/工作模式CBC/填充
        	Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        	
        	// 恢复秘钥对象
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
            
            // CBC模式需要生成一个16 bytes的initialization vector:
            SecureRandom sr = SecureRandom.getInstanceStrong();
            byte[] iv = sr.generateSeed(16); // 生成16个字节的随机数
            System.out.println(Arrays.toString(iv));
            IvParameterSpec ivps = new IvParameterSpec(iv); // 随机数封装成IvParameterSpec参数对象
            
            // 初始化秘钥:操作模式、秘钥、IV参数
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivps);
            
            // 加密
            byte[] data = cipher.doFinal(input);
            
            // IV不需要保密,把IV和密文一起返回:
            return join(iv, data);
        }
    
        // 解密:
        public static byte[] decrypt(byte[] key, byte[] input) throws GeneralSecurityException {
            // 把input分割成IV和密文:
            byte[] iv = new byte[16];
            byte[] data = new byte[input.length - 16];
            
            System.arraycopy(input, 0, iv, 0, 16); // IV
            System.arraycopy(input, 16, data, 0, data.length); //密文
            System.out.println(Arrays.toString(iv));
            
            // 解密:
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // 密码对象
            SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); // 恢复秘钥
            IvParameterSpec ivps = new IvParameterSpec(iv); // 恢复IV
            
            // 初始化秘钥:操作模式、秘钥、IV参数
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivps);
            
            // 解密操作
            return cipher.doFinal(data);
        }
        
        // 合并数组
        public static byte[] join(byte[] bs1, byte[] bs2) {
            byte[] r = new byte[bs1.length + bs2.length];
            System.arraycopy(bs1, 0, r, 0, bs1.length);
            System.arraycopy(bs2, 0, r, bs1.length, bs2.length);
            return r;
        }
    }
    

    在CBC模式下,需要随机生成一个16字节的IV参数,必须使用SecureRandom生成。因为多了一个IvOArameterSpec实例,因此初始化需要调用Cipher的重载方法并且传入IvParameterSpec/

    非对称加密:加密和解密使用的不是相同的密钥,只有同一个公钥-私钥对才能正常加解密。
    例如:小明要加密一个文件发送给小红,他应该首先向小红索取她的公钥,然后,他用小红的公钥加密,把加密文件发送给小红,此文件只能由小红的私钥解开,因为小红的私钥在她自己手里,所以,除了小红,没有任何人能解开此文件。

    非对称加密的典型算法就是RSA算法
    非对称加密的缺点:运算速度非常慢,比对称加密要慢很多

    在实际应用的时候,非对称加密总是和对称加密一起使用,假设小明需要给小红需要传输加密文件,他俩首先交换了各自的公钥,然后:
    1.小明生成一个随机的AES口令,然后用小红的公钥通过RSA加密这个口令,并发给小红;
    2.小红用自己的 RSA 私钥解密得到AES 口令;
    3.双方使用这个共享的AES 口令用 AES 加密通信。

    import java.math.BigInteger;
    import java.security.GeneralSecurityException;
    import java.security.KeyPair;
    import java.security.KeyPairGenerator;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import javax.crypto.Cipher;
    
    // RSA
    public class Main {
    	public static void main(String[] args) throws Exception {
    		// 明文:
    		byte[] plain = "Hello, encrypt use RSA".getBytes("UTF-8");
    
    		// 创建公钥/私钥对:
    		Human alice = new Human("Alice");
    
    		// 用Alice的公钥加密:
    		// 获取Alice的公钥,并输出
    		byte[] pk = alice.getPublicKey();
    		System.out.println(String.format("public key(公钥): %x", new BigInteger(1, pk)));
    
    		// 使用公钥加密
    		byte[] encrypted = alice.encrypt(plain);
    		System.out.println(String.format("encrypted(加密): %x", new BigInteger(1, encrypted)));
    
    		// 用Alice的私钥解密:
    		// 获取Alice的私钥,并输出
    		byte[] sk = alice.getPrivateKey();
    		System.out.println(String.format("private key(私钥): %x", new BigInteger(1, sk)));
    
    		// 使用私钥解密
    		byte[] decrypted = alice.decrypt(encrypted);
    		System.out.println("decrypted(解密): " + new String(decrypted, "UTF-8"));
    	}
    }
    
    // 用户类
    class Human {
    	// 姓名
    	String name;
    
    	// 私钥:
    	PrivateKey sk;
    
    	// 公钥:
    	PublicKey pk;
    
    	// 构造方法
    	public Human(String name) throws GeneralSecurityException {
    		// 初始化姓名
    		this.name = name;
    
    		// 生成公钥/私钥对:
    		KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");
    		kpGen.initialize(1024);
    		KeyPair kp = kpGen.generateKeyPair();
    
    		this.sk = kp.getPrivate();
    		this.pk = kp.getPublic();
    	}
    
    	// 把私钥导出为字节
    	public byte[] getPrivateKey() {
    		return this.sk.getEncoded();
    	}
    
    	// 把公钥导出为字节
    	public byte[] getPublicKey() {
    		return this.pk.getEncoded();
    	}
    
    	// 用公钥加密:
    	public byte[] encrypt(byte[] message) throws GeneralSecurityException {
    		Cipher cipher = Cipher.getInstance("RSA");
    		cipher.init(Cipher.ENCRYPT_MODE, this.pk); // 使用公钥进行初始化
    		return cipher.doFinal(message);
    	}
    
    	// 用私钥解密:
    	public byte[] decrypt(byte[] input) throws GeneralSecurityException {
    		Cipher cipher = Cipher.getInstance("RSA");
    		cipher.init(Cipher.DECRYPT_MODE, this.sk); // 使用私钥进行初始化
    		return cipher.doFinal(input);
    	}
    }
    
    展开全文
  • 常见哈希算法总结实现:

    多人点赞 2022-07-21 18:55:27
    哈希算法又称摘要算法,它的作用是对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希算法的目的为了验证原始数据是否被篡改。哈希算法最重要的特点就是●相同的输入一定得到相同的输出;●不同的输入大...
  • Java加密与安全 —— 常见哈希算法

    千次阅读 多人点赞 2022-07-21 19:13:47
    常见哈希算法
  • 哈希算法

    2020-08-17 15:01:34
    哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个对固定长度额输出摘要。 哈希算法最重要的特点就是: 相同的输入一定得到相同的输出; 不同的输入大概率得到不同的输出。 ...
  • JAVA加密算法之常见哈希算法总结

    多人点赞 2022-07-21 23:36:57
    哈希算法(Hash)又称摘要算法(Digest),它的作用是对任意一组输入数据进行计算,得到一个固定长度的输出摘要。哈希算法的目的为了验证原始数据是否被篡改。哈希算法最重要的特点就是●相同的输入一定得到相同的...
  • Java加密:常见哈希算法总结

    多人点赞 2022-07-21 18:53:13
    哈希算法总结以及简单应用实现代码
  • 加密与安全——哈希算法

    千次阅读 2021-03-15 21:02:44
    哈希算法(Hash)又称摘要算法(Digest),它的作用是:对任意一组输入数据进行计算,得到一个固定长度的输出摘要。 哈希算法最重要的特点就是: 相同的输入一定得到相同的输出; 不同的输入大概率得到不同的输出。...
  • 一致性哈希算法主要使用在分布式数据存储系统中,按照一定的策略将数据尽可能均匀分布到所有的存储节点上去,使得系统具有良好的负载均衡性能和扩展性。感觉一致性哈希与数据结构中的“循环队列”还是有一点联系的。...
  • 一致性哈希算法常用于负载均衡中要求资源被均匀的分布到所有节点上,并且对资源的请求能快速路由到对应的节点上。具体的举两个场景的例子: 1、MemCache集群,要求存储各种数据均匀的存到集群中的各个节点上,访问...
  • 哈希算法简单理解就是实现哈希函数的算法,用于将任意长度的二进制值串映射为固定长度的二进制值串,映射之后得到的二进制值就是哈希值(散列值)。 我们日常开发中最常见的哈希算法应用就是通过 md5 函数对数据...
  • 一致性哈希算法的作用及原理

    千次阅读 2020-09-07 08:58:48
    一致性哈希算法主要使用在分布式数据存储系统中,按照一定的策略将数据尽可能均匀分布到所有的存储节点上去,使得系统具有良好的负载均衡性能和扩展性。 1.简单哈希算法 哈希(hash)计算是常见的数据分布技术,其...
  • Java加密总结:常见哈希算法总结、对称加密算法与非对称加密算法的对比
  • 哈希算法说明及示例

    2020-10-30 16:24:37
    定义:哈希算法又叫散列算法,是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。它的原理其实很简单,就是把一段交易信息转换成一个固定长度的字符串 特点: 1. 信息相同,...
  • 写在前面哈希算法经常会被用到,比如我们Go里面的map,Java的HashMap,目前最流行的缓存Redis都大量用到了哈希算法。它们支持把很多类型的数据进行哈希计算,我们实际使用的时候并不用考虑哈希算法的实现。而其实...
  • 哈希算法和非对称加密算法的理解

    千次阅读 2020-02-19 18:46:05
    哈希算法又叫散列算法,是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。它的原理其实很简单,就是把一段交易信息转换成一个固定长度的字符串。 这串字符串具有一些特点: 1....
  • 复杂棋类游戏的搜索和估值通常比较耗时,为了提高棋类游戏的 AI,人们通常会使用置换表,置换表存储的是一些已知棋局...在各种哈希算法中,Zobrist 哈希算法简单实用,并且高效,在各种棋类游戏算法中得到了广泛的应...
  • 我是灼灼,一只初学Java的大一金渐层。 向往余秀华和狄兰·托马斯的疯狂,时常沉溺于将情感以诗相寄;追逐过王尔德、王小波的文字,后陷于毛姆...MD5加密的底层是由哈希算法来实现的 内容来自廖雪峰官方Java教程 哈.
  • 密码学之哈希算法

    万次阅读 2018-09-11 21:41:48
    1 哈希算法 哈希算法是将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,...
  • 哈希 算法

    2021-05-31 18:52:14
    哈希算法 基本概念:哈希算法是把一个无限的输入集合映射到一个有限的输出集合(散列值) 哈希算法最重要的特点就是: 相同的输入一定得到相同的输出; 不同的输入大概率得到不同的输出。 哈希算法的目的: 就是为了...
  • MATLAB 感知哈希算法 笔记

    千次阅读 2019-08-25 09:57:30
    的描述简单和个人的理解的写出了MATLAB代码,这里个简单记录。 第一步,缩小尺寸。 第二步,简化色彩。 第四步,比较像素的灰度。...%% 感知哈希简易算法进行图像搜索 % 这种算法的优点是简单快速,不受图...
  • 这里的关键技术叫做"感知哈希算法(aHash)"ashalgorithm),它的作用是对每张图片生成一个"指纹"(fingerprint)字符串,然后比较不同图片的指纹。结果越接近,就说明图片越相似第一步,缩小尺寸。将图片缩小到8x8的尺寸...
  • 学习MD2哈希算法第一手的参考资料是rfc1319文档,不过这个文档中有一处错误(关于Checksum计算),由于没留意勘误说明,这让我在当初趟了个大坑,按照文档描述计算得到的哈希怎么都不对。 如果您打算学习MD2算法,强烈...
  • 哈希算法乱谈(摘自知乎)

    千次阅读 2019-04-03 15:22:53
    最近初步了解了Hash算法的相关知识,一些人的见解让我能够迅速的了解相对不熟悉的知识,故想摘录下来,供以后温故而知新。 文章连接:https://www.zhihu.com/question/20820286 HASH算法是密码学的基础,比较常用...
  • 例如,如果发现任何更快的算法,aHash 将被更新以合并该技术。同样,如果发现 aHash 的 DOS 抵抗能力存在任何缺陷,aHash 将被更改以纠正该缺陷。 因为它没有固定的标准,不同的计算机或不同版本的代码上的计算机会...
  • 哈希算法详解

    2022-08-05 16:17:16
    哈希表的相关操作
  • 哈希/ *版权所有-Open Eth Mine以太坊矿业 有或没有源和二进制形式的重新分发和使用修改,只要满足以下条件满足: 重新分发源代码必须保留上述版权请注意,此条件列表和以下免责声明。 以二进制形式重新分发必须复制...
  • Java字符串的hashcode()就是一个哈希算法,输入任意字符串,输出固定的4字节int整数。碰撞是不能避免的,因为哈希算法是把一个无限的输入集合映射到一个有限的输出集合,必然会产生碰撞。2.不同的输入大概率得到不同...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,309
精华内容 8,923
关键字:

哈希算法用途