精华内容
下载资源
问答
  • 哈希加密详解
    2022-07-01 23:07:54

    哈希表

    哈希表是数组的一种扩展,底层依赖数组支持按照下标快速访问元素的特性,可以通过hash函数将元素的键值映射为下标,然后将对应下标的数据存储在数组中的对应位置。当按照键值查询元素时,使用相同的Hash函数将key转换为数组的下标,从数组中按照下标对应的位置获取数据。

    键必须唯一,不允许重复,每个key只能映射一个value,Hash冲突,由于映射的范围限制,key取值的可能性大于映射范围,出现两个不同的key映射到同一个位置

    哈希函数

    • 哈希函数计算达到的哈希值应该是一个非负整数
    • 如果key1==key2,那么hash(key1)==hash(key2)
    • 如果key1!=key2,那么hash(key1)!=hash(key2)。看起来合理,但实际上不可能实现,因为数组的存储空间有限,所以加大了哈希冲突的概率。

    即使两个key的hash值相等,但是又可能key值不相等

    哈希函数常常应用于:安全加密、唯一标识、数据校验、负载均衡、数据分片和分布式存储等,不同场景下对哈希函数的要求不同

    哈希冲突

    解决哈希冲突的常见方法有开放地址法和链表法
    开放地址法: 一旦出现Hash值冲突则通过重新位置的探索整个哈希表,时间复杂度为O(n)
    链表法: 链地址法,再具体的应用中使用较多,在哈希表汇总每个桶对应一个链表,把哈希值相同的元素存放在相同桶位置的对应链表中,由于需要对比key值所以插入时间复杂度为O(k),查找和删除时的时间复杂度与链表的长度成正比O(k),一般当k值不是很大时可以粗略的认为O(1)。需要尽量减少链表长度,可以引入一个参数:负载因子。负载因子用于间接的限定链表的长度,如果值越大则允许的链表长度越长,哈希表的性能越差,但是加载因子越小空浪费越严重。

    哈希表的设计

    哈希函数的设计首先不能过于复杂,复杂的哈希函数会间接的影响hash表的性能;其次要求哈希值应该尽可能随机且均匀分布,避免或者减少哈希冲突的数量,使每个桶中存储的数据比较平均常规的设计方法有数据分析法,选择数据的业务特征提取部分数据进行计算,然后得到结果再与哈希表数组的长度求余后最为哈希值。另外还有直接寻址法、平方取中法、折叠法和随机数法等。

    加载因子问题

    加载因子越大,哈希表中存储的元素越多,空闲的位置就越少,哈希冲突的概率就越大,插入、删除和
    查找数据时的性能就随之降低。
    针对静态数据集是比较容易处理的,但是动态数据集无法申请一个足够大的哈希表,所以必须考虑扩容
    问题。扩容实际上就是重新申请内存空间,重新计算每个数据的哈希值,并且将数据从原来的hash表搬
    移到新的哈希表中,最坏的情况下O(n),从道理上来说,利用时间复杂度的摊还分析法,摊还后时间复
    杂度可以接近最好的时间复杂度。但是针对本次操作绝对是一个问题
    一般来说在空间和时间之间进行平衡,如果内存空间不紧张,对执行效率要求较高,可以选择小一点的
    阈值;相反如果内存空间比较紧张,对执行效率要求不高,可以适当选择大一点的阈值,甚至在基于链
    表法的实现中可以大于1

    扩容

    扩容处理相对于增删来说是非常低效的,如果相应时间要求高,尽管大部分情况下,插入数据的速度很
    快,但是极个别情况插入速度非常慢,会导致用户崩溃的。就是扩容时每次扩容是容积乘以2,因为扩容
    处理后的元素有2种情况,一种是位置不变,一种后移同上一次容积
    例如原始数组长度为16,则原始hash值为16\32\48\0对应的位置都是0;当扩容到32时,会发现0\32位
    置不变,但是16\48后移16个位置

    更多相关内容
  • 在所有的加密算法中使用最多的就是哈希加密了,很多人第一次接触的加密算法如MD5、SHA1都是典型的哈希加密算法,而哈希加密除了用在密码加密上,它还有很多的用途,如提取内容摘要、生成签名、文件对比、区块链等等...

    前言

    在所有的加密算法中使用最多的就是哈希加密了,很多人第一次接触的加密算法如MD5、SHA1都是典型的哈希加密算法,而哈希加密除了用在密码加密上,它还有很多的用途,如提取内容摘要、生成签名、文件对比、区块链等等。这篇文章就是想详细的讲解一下哈希加密,并分享一个哈希加密的工具类。

    概述

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

    它的函数表达式为:h=H(m)

    无论输入是什么数字格式、文件有多大,输出都是固定长度的比特串。以比特币使用的Sh256算法为例,无论输入是什么数据文件,输出就是256bit。

    哈希算法

    把网址A,转换成数字1。网址B,转换成数字2。

    一个网址X,转换成数字N,根据数字N作为下标,就可以快速地查找出网址X的信息。这个转换的过程就是哈希算法。

    比如这里有一万首歌,给你一首新的歌X,要求你确认这首歌是否在那一万首歌之内。

    无疑,将一万首歌一个一个比对非常慢。但如果存在一种方式,能将一万首歌的每首数据浓缩到一个数字(称为哈希码)中,于是得到一万个数字,那么用同样的算法计算新的歌X的编码,看看歌X的编码是否在之前那一万个数字中,就能知道歌X是否在那一万首歌中。

    作为例子,如果要你组织那一万首歌,一个简单的哈希算法就是让歌曲所占硬盘的字节数作为哈希码。这样的话,你可以让一万首歌“按照大小排序”,然后遇到一首新的歌,只要看看新的歌的字节数是否和已有的一万首歌中的某一首的字节数相同,就知道新的歌是否在那一万首歌之内了。

    一个可靠的哈希算法,应该满足:

    对于给定的数据M,很容易算出哈希值X=F(M);

    根据X很难反算出M;

    很难找到M和N使得F(N)=F(M)

    总结哈希加密的特点

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

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

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

    4. 抗碰撞性:理想的Hash函数是无碰撞的,但在实际算法的设计中很难做到这一点。
      有两种抗碰撞性:一种是弱抗碰撞性,即对于给定的消息,要发现另一个消息,满足在计算上是不可行的;另一种是强抗碰撞性,即对于任意一对不同的消息,使得在计算上也是不可行的。

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

    哈希加密并非不可破解,2004年,王小云教授在国际密码学大会上公布了破解Hash函数的关键技术。

    哈希加密和对称/非对称加密对比

    在这里插入图片描述
    主要有这些区别:

    1. 哈希密码是不可逆的,因此无法从密文中获取到原文,而对称/非对称加密可以;
    2. 哈希密码加密大部分不需要密钥(除了HMAC),而对称/非对称加密需要;
    3. 哈希加密不管是短数据还是长数据,加密后得到的密文长度是固定的,而对称/非对称通常和原文的长度成正比;
    4. 哈希加密有可能碰撞,虽然理论的哈希加密是不可能碰撞的,但是只是理论,王小云教授之前就提出碰撞的方法。而对于对称/非对称,一个密文用密钥解密后的结果一定是唯一的;

    常见的加密算法

    MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。这套算法的程序在 RFC 1321 标准中被加以规范。1996年后该算法被证实存在弱点,可以被加以破解,对于需要高度安全性的数据,专家一般建议改用其他算法,如SHA-2。2004年,证实MD5算法无法防止碰撞(collision),因此不适用于安全性认证,如SSL公开密钥认证或是数字签名等用途。

    SHA-1(英语:Secure Hash Algorithm 1,中文名:安全散列算法1)是一种密码散列函数,美国国家安全局设计,并由美国国家标准技术研究所(NIST)发布为联邦数据处理标准(FIPS)。SHA-1可以生成一个被称为消息摘要的160位(20字节)散列值,散列值通常的呈现形式为40个十六进制数。
    SHA-1已经不再视为可抵御有充足资金、充足计算资源的攻击者。2005年,密码分析人员发现了对SHA-1的有效攻击方法,这表明该算法可能不够安全,不能继续使用,自2010年以来,许多组织建议用SHA-2或SHA-3来替换SHA-1。Microsoft、Google以及Mozilla都宣布,它们旗下的浏览器将在2017年前停止接受使用SHA-1算法签名的SSL证书。
    2017年2月23日,CWI Amsterdam与Google宣布了一个成功的SHA-1碰撞攻击,发布了两份内容不同但SHA-1散列值相同的PDF文件作为概念证明。

    SHA-2/SHA-256
    SHA-2有多种不同的位数,导致这个名词有一些混乱。但是无论是“SHA-2”,“SHA-256”或“SHA-256位”,其实都是指同一种加密算法。但是SHA-224”,“SHA-384”或“SHA-512”,表示SHA-2的二进制长度。还要另一种就是会把算法和二进制长度都写上,如“SHA-2 384”。
    SSL行业选择SHA作为数字签名的散列算法,从2011到2015,一直以SHA-1位主导算法。但随着互联网技术的提升,SHA-1的缺点越来越突显。从去年起,SHA-2成为了新的标准,所以现在签发的SSL证书,必须使用该算法签名。
    也许有人偶尔会看到SHA-2 384位的证书,很少会看到224位,因为224位不允许用于公共信任的证书,512位,不被软件支持。
    初步预计,SHA-2的使用年限为五年,但也许会被提前淘汰。这需要时间来验证。
    在这里插入图片描述

    HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写,由H.Krawezyk,M.Bellare,R.Canetti于1996年提出的一种基于Hash函数和密钥进行消息认证的方法,并于1997年作为RFC2104被公布,并在IPSec和其他网络协议(如SSL)中得以广泛应用,现在已经成为事实上的Internet安全标准。它可以与任何迭代散列函数捆绑使用。
    HMAC运算利用hash算法,以一个消息M和一个密钥K作为输入,生成一个定长的消息摘要作为输出。HMAC算法利用已有的Hash函数,关键问题是如何使用密钥。
    在这里插入图片描述
    HMAC的密钥长度可以是任意大小,如果小于n(hash输出值的大小),那么将会消弱算法安全的强度。建议使用长度大于n的密钥,但是采用长度大的密钥并不意味着增强了函数的安全性。密钥应该是随机选取的,可以采用一种强伪随机发生器,并且密钥需要周期性更新,这样可以减少散列函数弱密钥的危险性以及已经暴露密钥所带来的破坏
    使用SHA-1、SHA-224、SHA-256、SHA-384、SHA-512所构造的HMAC,分别称为HMAC-SHA1、HMAC-SHA-224、HMAC-SHA-384、HMAC-SHA-512。
    HMAC算法更象是一种加密算法,它引入了密钥,其安全性已经不完全依赖于所使用的Hash算法,安全性主要有以下几点保证。
    (1)使用的密钥是双方事先约定的,第三方不可能知道。作为非法截获信息的第三方,能够得到的信息只有作为“挑战”的随机数和作为“响应”的HMAC 结果,无法根据这两个数据推算出密钥。由于不知道密钥,所以无法仿造出一致的响应。
    (2)HMAC与一般的加密重要的区别在于它具有“瞬时"性,即认证只在当时有效,而加密算法被破解后,以前的加密结果就可能被解密。
    HMAC的安全性依赖于散列函数H的密码学属性:①抗碰撞属性;②当应用于一个单独的消息分组时H的压缩函数的消息认证属性 。

    四种算法的用途:MD5、SHA-1可以在一些数据量较小的情况下用来生成信息摘要,他们生成的摘要长度较短,加密速度快,但是摘要长度较短,有碰撞的可能;SHA-256可以用来对一些大数据量的数据来进行加密、或者生成信息摘要,基于它的长摘要长度,碰撞的可能性较低;HMAC引入了密钥,因此其安全性最高,可以很好的用在对密码的加密上;

    JAVA工具类

    package cn.hengyumo.humor.utils;
    
    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.codec.binary.Hex;
    
    import javax.crypto.Mac;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    /**
     * HeaUtil
     * Hash encryption algorithm
     * 哈希加密算法:MD5、SHA-1、SHA-256、HMAC-SHA-1、HMAC-SHA-256
     * 需要导入 org.apache.commons.codec 包
     *
     * @author hengyumo
     * @version 1.0
     * @since 2019/11/12
     */
    @SuppressWarnings("WeakerAccess")
    public class HeaUtil {
    
        /**
         * md5加密
         *
         * @param text 内容
         * @return digest 摘要
         * @throws NoSuchAlgorithmException e
         */
        public static String md5(String text) throws NoSuchAlgorithmException {
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            byte[] bytes = messageDigest.digest(text.getBytes());
            return Hex.encodeHexString(bytes);
        }
    
        /**
         * sha1加密
         *
         * @param text 内容
         * @return digest 摘要
         * @throws NoSuchAlgorithmException e
         */
        public static String sha1(String text) throws NoSuchAlgorithmException {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
            byte[] bytes = messageDigest.digest(text.getBytes());
            return Hex.encodeHexString(bytes);
        }
    
        /**
         * sha256加密
         *
         * @param text 内容
         * @return digest 摘要
         * @throws NoSuchAlgorithmException e
         */
        public static String sha256(String text) throws NoSuchAlgorithmException {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            byte[] bytes = messageDigest.digest(text.getBytes());
            return Hex.encodeHexString(bytes);
        }
    
        /**
         * hmac-sha1加密
         *
         * @param text 内容
         * @param key 密钥
         *
         * @return 密文
         * @throws Exception e
         */
        public static String hmacSha1(String text, String key) throws Exception {
            SecretKeySpec sk = new SecretKeySpec(key.getBytes(), "HmacSHA1");
            return hmacSha1(text, sk);
        }
    
        /**
         * hmac-sha1加密
         *
         * @param text 内容
         * @param sk 密钥
         *
         * @return 密文
         * @throws Exception e
         */
        public static String hmacSha1(String text, SecretKeySpec sk) throws Exception {
            Mac mac = Mac.getInstance("HmacSHA1");
            mac.init(sk);
            byte[] rawHmac = mac.doFinal(text.getBytes());
            return new String(Base64.encodeBase64(rawHmac));
        }
    
        /**
         * 生成 HmacSha1 密钥
         *
         * @param key 密钥字符串
         * @return SecretKeySpec
         */
        public static SecretKeySpec createHmacSha1Key(String key) {
            return new SecretKeySpec(key.getBytes(), "HmacSHA1");
        }
    
        /**
         * hmac-sha256加密
         *
         * @param text 内容
         * @param key 密钥
         *
         * @return 密文
         * @throws Exception e
         */
        public static String hmacSha256(String text, String key) throws Exception {
            SecretKeySpec sk = new SecretKeySpec(key.getBytes(), "HmacSHA256");
            return hmacSha1(text, sk);
        }
    
        /**
         * hmac-sha256加密
         *
         * @param text 内容
         * @param sk 密钥
         *
         * @return 密文
         * @throws Exception e
         */
        public static String hmacSha256(String text, SecretKeySpec sk) throws Exception {
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(sk);
            byte[] rawHmac = mac.doFinal(text.getBytes());
            return new String(Base64.encodeBase64(rawHmac));
        }
    
        /**
         * 生成 HmacSha256 密钥
         *
         * @param key 密钥字符串
         * @return SecretKeySpec
         */
        public static SecretKeySpec createHmacSha256Key(String key) {
            return new SecretKeySpec(key.getBytes(), "HmacSHA256");
        }
    
        /**
         * 测试
         *
         * @param args args
         */
        public static void main(String[] args) throws Exception {
            String s = "123456789了踩踩踩";
            System.out.println(md5(s));
            System.out.println(sha1(s));
            System.out.println(sha256(s));
            String k = "ada232@12";
            System.out.println(hmacSha1(s, k));
            s = "aeqnfoavneornqoenr1啊可是到了南方情况无法弄清了我呢010jownfasdfqijqor";
            System.out.println(hmacSha1(s, k));
            SecretKeySpec sk1 = createHmacSha1Key(k);
            System.out.println(hmacSha1(s, sk1));
            SecretKeySpec sk256 = createHmacSha256Key(k);
            System.out.println(hmacSha256(s, sk256));
        }
    }
    
    
    

    输出

    d415ffe55bf2e18b9e059be4ab371fe7
    15b03a4189d24ca3459e199bbf8de7fc3e4d68f3
    e32b84b738416e91198112a57d295ba685a40e55bb114725e8a444efd53d5a01
    ck66ZAkPEh+19UIgnX775N3nLyc=
    WVJAs/+6OlwkzM1ZEK+t8iMgtyc=
    WVJAs/+6OlwkzM1ZEK+t8iMgtyc=
    E1sXoiPtnjzMiDRagp08Lt3gBKXE/EU+nLJZpy8hURc=
    
    

    备注

    使用需要导入maven或jar包

    
            <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
            <dependency>
                <groupId>commons-codec</groupId>
                <artifactId>commons-codec</artifactId>
                <version>1.12</version>
            </dependency>
    
    

    用途探讨

    1. 文件、图片等数据的标识码
      对文件进行md5加密,得到一个唯一的文件摘要,把摘要存储,之后再次上传文件时前端先计算摘要,如果文件的摘要在后端发现重复的,那么就不进行上传。这样可以为服务器节省大量的硬盘资源。这主要利用了哈希加密的压缩性、唯一性;
    2. 密码加密存储
      密码如果明文存储到数据库是不安全的,这时可以在存储之前先用sha1或者sha256等算法进行加密,加密后进行存储,利用哈希加密的不可逆性,保证了密码存储的安全性,防止密码泄露。
    3. 生成数字签名、防止篡改
      所谓的签名,指的是对于一份数据,拥有独一无二的标识=》这标识就是数字签名。生成数字签名的方法就是用md5等哈希算法生成摘要,并将摘要公开,对方获得数据之后,通过再次进行哈希生成摘要后对比公开摘要,就可以确认文件是不是原始的那份,而不是被篡改过的;这主要利用了哈希加密的高灵敏性,消息M的任何改变都会导致哈希值H(M)发生改变。即如果输入有微小不同,哈希运算后的输出一定不同。
    4. 防止查表法
      所谓查表法针对的就是md5、sha1等哈希加密算法,黑客预先收集一些常用的密码存入表中,预先对表中的密码计算md5、sha1值,之后就可以通过对比表和数据库的密文,来获取到密码的明文;防止查表法的方式有加盐、或者使用HMAC这样的密钥哈希算法,从而使得查表法失效。

    参考&引用

    通俗易懂的哈希算法讲解
    https://blog.csdn.net/zongyue_wang/article/details/81947142
    MD5
    https://baike.baidu.com/item/MD5/212708?fr=aladdin
    SHA-1
    https://baike.baidu.com/item/SHA-1/1699692?fromtitle=SHA1&fromid=8812671&fr=aladdin
    散列算法:SHA-1,SHA-2和SHA-256之间的区别(下)
    https://www.jianshu.com/p/68c664b663f4
    hmac
    https://baike.baidu.com/item/hmac/7307543?fr=aladdin
    HMAC的图解
    https://blog.csdn.net/chengqiuming/article/details/82822933

    展开全文
  • 明文存储:肉眼就可以识别,没有任何安全性。... 加盐哈希加密:加密时混入一段“随机”字符串(盐值)再进行哈希加密。即使密码相同,如果盐值不同,那么哈希值也是不一样的。现在网站开发中主要是运用这种加密方法。
  • 本文主要介绍了详解python实现可视化的MD5、sha256哈希加密小工具,分享给大家,具体如下: 效果图: 刚启动的状态 输入文本、触发加密按钮后支持复制 超过十条不全量显示 代码 import hashlib import tkinter ...
  • 我们所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的Bytes。 所以当我们在Python中进行加密操作的时候,要确保我们操作的是Bytes,否则就会报错。 将字符串和Bytes互相转换可以使用...
  • 下面有一个列表,列出了Django 支持的哈希算法类。列表的第一个元素 (即settings.PASSWORD_HASHERS[0]) 会用于储存密码, 所有其它元素都是用于验证的哈希值,它们可以用于检查现有的密码。意思是如果你打算使用不同...
  • 一致性哈希算法详解

    2021-10-06 10:38:51
    一、什么是哈希 散列表,是根据键直接访问在指定储存位置数据的数据结构。通过计算一个关于键的函数也称为哈希函数,将所需查询的数据映射到表中一个位置来访问记录,加快查找速度。这个映射函数称做「散列函数」...

    一、什么是哈希

    散列表,是根据键直接访问在指定储存位置数据的数据结构。通过计算一个关于键的函数也称为哈希函数,将所需查询的数据映射到表中一个位置来访问记录,加快查找速度。这个映射函数称做「散列函数」,存放记录的数组称做散列表。

    散列函数能使对一个数据序列的访问过程更加迅速有效,是一种空间换时间的算法,通过散列函数数据元素将被更快定位。

    二、常见的hash算法

    MD5算法

    MD5消息摘要算法(MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),MD5算法将数据(如一段文字)运算变为另一固定长度值,是散列算法的基础原理。由美国密码学家 Ronald Linn Rivest设计,于1992年公开并在 RFC 1321 中被加以规范。

    CRC算法

    循环冗余校验(Cyclic Redundancy Check)是一种根据网络数据包或电脑文件等数据,产生简短固定位数校验码的一种散列函数,由 W. Wesley Peterson 于1961年发表。生成的数字在传输或者存储之前计算出来并且附加到数据后面,然后接收方进行检验确定数据是否发生变化。由于本函数易于用二进制的电脑硬件使用、容易进行数学分析并且尤其善于检测传输通道干扰引起的错误,因此获得广泛应用。

    MurmurHash

    MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。由 Austin Appleby 在2008年发明,并出现了多个变种,与其它流行的哈希函数相比,对于规律性较强的键,MurmurHash的随机分布特征表现更良好。

    这个算法已经被很多开源项目使用,比如libstdc++ (4.6版)

    三、常用的散列方法:

    1.直接定址法:取关键字或关键字的某个线性函数值为散列地址,这个线性函数的定义多种多样,没有标准。

    2.数字分析法:假设关键字是以r为基的数,并且哈希表中可能出现的关键字都是事先知道的,则可取关键字的若干数位组成哈希地址。

    3.平方取中法:取关键字平方后的中间几位为哈希地址。通常在选定哈希函数时不一定能知道关键字的全部情况,取其中的哪几位也不一定合适,而一个数平方后的中间几位数和数的每一位都相关,由此使随机分布的关键字得到的哈希地址也是随机的,取的位数由表长决定。

    4.折叠法:将关键字分割成位数相同的几部分(最后一部分的位数可以不同),然后取这几部分的叠加和(舍去进位)作为哈希地址。

    5.取模法:取关键字被某个不大于散列表表长 m 的数 p 除后所得的余数为散列地址。即 hash(key) = key % p(p<= M),不仅可以对关键字直接取模,也可在折叠法、平方取中法等运算之后取模。对 p 的选择很重要,一般取素数或 m,若 p 选择不好,容易产生冲突。

    四、普通hash算法存在的问题

    如果我们需要对mysql数据库进行分库分表,如分成三张表,那么我们如果使用普通hash的话,假设我们选择取模法,需要选一个字段对3取余,成功分区如下

    
    1 % 3 = 1
    2 % 3 = 2
    3 % 3 = 0
    4 % 3 = 1
    5 % 3 = 2
    6 % 3 = 0

    这时候呢如果我们需要分成4张表这时候就需要对4取余

    
    1 % 4 = 1
    2 % 4 = 2
    3 % 4 = 3
    4 % 4 = 0
    5 % 4 = 1
    6 % 4 = 2

    如果我们想查3应该去3这个分区,按照之前的hash却是去0,数据乱了,新加入的数据还好可以按照新的映射关系,但是老的数据是没办法修改的,需要对全部的数据重新计算hash才能不影响到查询,这个工作量基本是不可实现的,所以这时候就需要使用一致性hash算法

    五、一致性hash算法--hash环

    一致性哈希算法(Consistent Hashing)最早在论文《Consistent Hashing and Random Trees: Distributed Caching Protocols for Relieving Hot Spots on the World Wide Web》中被提出。简单来说,一致性哈希将整个哈希值空间组织成一个虚拟的圆环,如假设某哈希函数H的值空间为0-2^32-1(即哈希值是一个32位无符号整形),整个哈希空间环如下:

    还是以上面mysql分库分表的例子:

    下一步将各个表使用Hash进行一个哈希,具体可以选择表中的唯一整数型字段进行哈希,这样每台机器就能确定其在哈希环上的位置,哈希后在环空间的位置如下: 

     这样就相当于hash值在0-1073741824的在第一张表,1073741824-2147483648的在第二张表,2147483648-3221225472在第三张表,3221225472-4294967296在第四张表

    如果说后续需要添加节点,如加个表五,那么只需要随便选个节点,比如将第一个表中数据复制一半到新的表中就可以其他映射关系都不会收到影响

    一致性hash存在的最大问题是会产生数据偏移,所以一般都是倍数扩容

    六、 一致性hash算法应用--redis虚拟槽技术

    虚拟槽技术应用于redis集群分区,具体可以看https://blog.csdn.net/zhang09090606/category_10909179.html?spm=1001.2014.3001.5482

    1.虚拟槽技术
    虚拟槽分区巧妙地使用了哈希空间,槽并不是真实存在只是逻辑上的,使用分散度良好的哈希函数把所有 数据映射到一个固定范围的整数集合中,整数定义为槽(slot )。这个范围 一般远远大于节点数,比如Redis Cluster 槽范围是 0~16383 。槽是集群内数据 管理和迁移的基本单位。采用大范围槽的主要目的是为了方便数据拆分和集群扩展。每个节点会负责一定数量的槽如下图,每个节点管理了3276个槽

    2.数据分配:

    当插入数据时分以下步骤

    (1)首先通过CRC16算法算出redis key的散列值

    (2)将此散列值对槽数也就是16383取余算出该数据应该进入到哪个槽中

    (3)redis会根据管理的映射关系查到该槽归哪个节点管理

    (4)将该数据放入该节点中

    3.节点的伸缩:

    当新增一个节点时,例如插入node-6时发生了以下操作
    (1)将node-1管理的槽分配一半给node-6,此时node-1管理的槽为0-1638,node-6管理的槽为1639-3276

    (2)将node-1中分配出去的槽对应的数据复制到node-6中

    4.虚拟槽技术的优点

    (1)伸缩时无需复制大量数据,只需复制一个节点的一半数据即可

    (2)可以单个新增,即便不倍数扩容也可以保证映射关系,但是实际还是建议倍数扩容,不然会发生数据偏移(有的节点数据多有的节点数据少 )
     

    展开全文
  • 主要介绍了密码哈希函数 Bcrypt的最大密码长度限制详解的相关资料,需要的朋友可以参考下
  • 简介 几种破解哈希加密的方法

    万次阅读 2018-03-09 14:23:22
    破解哈希加密: 破解哈希加密最简单的办法,就是去猜,将每个猜测值哈希之后的结果和目标值比对,如果相同则破解成功 我们没有办法阻止字典攻击和暴击攻击,尽管可以降低它们的效率,但那也不是完全阻止。如果你的...

    破解哈希加密:
    破解哈希加密最简单的办法,就是去猜,将每个猜测值哈希之后的结果和目标值比对,如果相同则破解成功
    我们没有办法阻止字典攻击和暴击攻击,尽管可以降低它们的效率,但那也不是完全阻止。如果你的密码哈希系统足够安全,唯一的破解办法就是进行字典攻击或者暴力遍历每一个哈希值
    参考资料:
    http://blog.jobbole.com/61872/

    破解哈希加密的办法详解注释
    字典攻击字典攻击需要使用一个字典文件,它包含单词、短语、常用密码以及其他可能用作密码的字符串。其中每个词都是进过哈希后储存的,用它们和密码哈希比对,如果相同,这个词就是密码。字典文件的构成是从大段文本中分解出的单词,甚至还包括一些数据库中真实的密码。然后还可以对字典文件进行更进一步的处理使它更有效,比如把单词中的字母替换为它们的“形近字”(hello变为h3110)我们没有办法阻止字典攻击和暴击攻击,尽管可以降低它们的效率,但那也不是完全阻止
    暴力攻击暴力攻击会尝试每一个在给定长度下各种字符的组合。这种攻击会消耗大量的计算,也通常是破解哈希加密中效率最低的办法,但是它最终会找到正确的密码。因此密码需要足够长,以至于遍历所有可能的字符串组合将耗费太长时间,从而不值得去破解它如果你的密码哈希系统足够安全,唯一的破解办法就是进行字典攻击或者暴力遍历每一个哈希值。
    查表法查表法对于破解一系列算法相同的哈希值有着无与伦比的效率。主要的思想就是预计算密码字典中的每个密码,然后把哈希值和对应的密码储存到一个用于快速查询的数据结构中。一个良好的查表实现可以每秒进行数百次哈希查询,即使表中储存了几十亿个哈希值
    反向查表法这种方法可以使攻击者同时对多个哈希值发起字典攻击或暴力攻击,而不需要预先计算出一个查询表。 首先攻击者构造一个基于密码-用户名的一对多的表,当然数据需要从某个已经被入侵的数据库获得,然后猜测一系列哈希值并且从表中查找拥有此密码的用户。通常许多用户可能有着相同的密码,因此这种攻击方式也显得尤为有效。
    彩虹表彩虹表是一种在时间和空间的消耗上找寻平衡的破解技术。它和查表法很类似,但是为了使查询表占用的空间更小而牺牲了破解速度。因为它更小,于是我们可以在一定的空间内存储更多的哈希值,从而使攻击更加有效。能够破解任何8位及以下长度MD5值的彩虹表已经出现了
    加盐一种让查表法和彩虹表都失去作用的技术,叫做加盐查表法和彩虹表只有在所有密码都以相同方式进行哈希加密时才有效。 如果两个用户密码相同,那么他们密码的哈希值也是相同的。我们可以通过“随机化”哈希来阻止这类攻击,于是当相同的密码被哈希两次之后,得到的值就不相同了。 比如可以在密码中混入一段“随机”的字符串再进行哈希加密,这个被字符串被称作盐值。如同上面例子所展示的,这使得同一个密码每次都被加密为完全不同的字符串。为了校验密码是否正确,我们需要储存盐值。通常和密码哈希值一起存放在账户数据库中,或者直接存为哈希字符串的一部分。 盐值并不需要保密,由于随机化了哈希值,查表法、反向查表法和彩虹表都不再有效。攻击者无法确知盐值,于是就不能预先计算出一个查询表或者彩虹表。这样每个用户的密码都混入不同的盐值后再进行哈希,因此反向查表法也变得难以实施
    展开全文
  • “如果你不信任他们,你就把数据加密。”这是数据安全专家常常挂在嘴边的一句话。部署在企业内部的数据中心,由于单位组织完全控制全部的软/硬件设备,所以数据要不要加密由企业规章制度界定。 但是在云端,多个互不...
  • 我们常常为了避免在服务器受到攻击,数据库被拖库时,用户的明文密码不被泄露,一般会对密码进行单向不可逆加密——哈希。 常见的方式是: 哈希方式 加密密码 md5(‘123456′) e10adc3949ba59abbe56e057f20f883...
  • 在这个模块中已经打包了OpenSSL hash, HMAC(哈希信息验证码),cipher(加密),decipher(解密),sign(签名)以及verify(验证)的功能。 加密算法crypto 我很难想象在php里面md5加密只是三个字符的一个方法而已...
  • MD5加密详解

    千次阅读 2021-12-27 19:58:06
    MD5加密详解 加密过程: 密码:123456 (明文形式)----->加密后 49ba59abbe56e057 1.密码在请求提交后到达控制器 2.到达控制后通过加密规则,转换成密文 3.在经过DAO查询与数据库中已经存在的密文密码比对是否...
  • 编解码和加密详解

    2021-09-16 11:59:50
    常见加密算法2.1 什么是加密算法2.2 MD5算法2.3 SHA1算法2.4 HMAC算法3. 结论 1. 编码和解码(encode/decode)算法 简单理解,编码就是把信息按照一定的规则进行组织,变换消息形式的过程,所谓解码就是把收到的信息...
  • 0、摘要 今天看到吉日嘎拉的一篇关于管理软件中信息加密和安全的文章,感觉非常有实际意义。文中作者从实践经验出发,讨论了...本文不对哈希加密做过于深入的讨论,而是对哈希加密的基本概念和原理进行阐述、比...
  • 主要介绍了详解Java中实现SHA1与MD5加密算法的基本方法,安全哈希算法第一版和消息摘要算法第五版也是通常人们最常用的加密算法,需要的朋友可以参考下
  • 1、Hash主要用于信息安全领域中加密算法,它把一些不同长度的信息转化成杂乱的12 2、查找:哈希表,又称为散列,是一种更加快捷的查找技术 3、Hash表在海量
  • 密码学系列之:bcrypt加密算法详解

    万次阅读 2021-09-16 10:19:13
    今天要给大家介绍的一种加密算法叫做bcrypt, bcrypt是由Niels Provos和David Mazières设计的密码哈希函数,他是基于Blowfish密码而来的,并于1999年在USENIX上提出。 除了加盐来抵御rainbow table 攻击之外,bcrypt...
  • HTTPS加密过程详解

    千次阅读 多人点赞 2022-03-03 10:59:47
    文章目录HTTPS协议加密的相关概念HTTPS工作过程对称加密非对称加密中间人攻击引入证书机制 HTTPS协议 HTTPS协议也是应用层的一种网络协议,与HTPP协议报文格式都一样,仅在HTTP协议的基础上,引入了加密层。由于...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,283
精华内容 2,513
热门标签
关键字:

哈希加密详解